├── .gitmodules ├── tests ├── integer.tail ├── basic_tests │ ├── negi.apl │ ├── addi.apl │ ├── eqiFalse.apl │ ├── first.apl │ ├── gtiTrue.apl │ ├── iotaV.apl │ ├── ltei.apl │ ├── maxi.apl │ ├── mini.apl │ ├── multi.apl │ ├── negd.apl │ ├── not0.apl │ ├── not1.apl │ ├── powi.apl │ ├── shape.ok │ ├── signd.apl │ ├── signi.apl │ ├── subi.apl │ ├── abcd.ok │ ├── addd.apl │ ├── addd.ok │ ├── addi.ok │ ├── cat.ok │ ├── catV.ok │ ├── ceil.ok │ ├── circ.ok │ ├── cons.ok │ ├── cons1.ok │ ├── divd.ok │ ├── divi.apl │ ├── divi.ok │ ├── drop.ok │ ├── drop2.ok │ ├── each.ok │ ├── eachV.ok │ ├── easter.ok │ ├── eqiTrue.apl │ ├── expd.ok │ ├── first.ok │ ├── first2.ok │ ├── first3.ok │ ├── gtdTrue.apl │ ├── gteiTrue.apl │ ├── i2d.ok │ ├── idx.ok │ ├── iotaV.ok │ ├── ltdTrue.apl │ ├── lted.apl │ ├── lted.ok │ ├── ltei.ok │ ├── lteiTrue.apl │ ├── ltiTrue.apl │ ├── maxd.apl │ ├── maxd.ok │ ├── maxi.ok │ ├── mini.ok │ ├── muld.apl │ ├── muld.ok │ ├── multi.ok │ ├── negd.ok │ ├── negi.ok │ ├── not0.ok │ ├── not1.ok │ ├── orTrue.ok │ ├── ori.apl │ ├── ori.ok │ ├── powd.ok │ ├── powi.ok │ ├── powtup.ok │ ├── rav.ok │ ├── red.ok │ ├── red2.ok │ ├── rev.ok │ ├── rev2.ok │ ├── rot.ok │ ├── rot0.ok │ ├── scan.ok │ ├── signd.ok │ ├── signi.ok │ ├── sort.ok │ ├── subd.apl │ ├── subd.ok │ ├── subi.ok │ ├── sum35.ok │ ├── take.ok │ ├── take1.ok │ ├── take2.ok │ ├── vowels.ok │ ├── vrot.ok │ ├── zilde.ok │ ├── andbTrue.apl │ ├── andbTrue.ok │ ├── boolean.ok │ ├── compress.ok │ ├── divd.apl │ ├── drop2.apl │ ├── drop2Dim.ok │ ├── drop3Dim.ok │ ├── dtransp.ok │ ├── eqdFalse.apl │ ├── eqdFalse.ok │ ├── eqiFalse.ok │ ├── eqiTrue.ok │ ├── fibpow.ok │ ├── firstV2.ok │ ├── firstV3.ok │ ├── gradeupdown.ok │ ├── gtdTrue.ok │ ├── gtedFalse.apl │ ├── gtedFalse.ok │ ├── gteiTrue.ok │ ├── gtiTrue.ok │ ├── ltdTrue.ok │ ├── lteiTrue.ok │ ├── ltiTrue.ok │ ├── mult.ok │ ├── mult0.ok │ ├── orFalse.apl │ ├── orFalse.ok │ ├── orTrue.apl │ ├── powscl.apl │ ├── powscl.ok │ ├── primes.ok │ ├── primes0.ok │ ├── reduce2.ok │ ├── reduce3.ok │ ├── replicate.ok │ ├── reshape.ok │ ├── reshape2.ok │ ├── rotateRank1.ok │ ├── rotateRank2.ok │ ├── slashbar.ok │ ├── snocRank1.ok │ ├── snocRank2.ok │ ├── spinpow.ok │ ├── take1neg.ok │ ├── timespi.ok │ ├── transp2.ok │ ├── transp3.ok │ ├── transpAPL.ok │ ├── xorbTrue.apl │ ├── xorbTrue.ok │ ├── zipWith.ok │ ├── zipWith2.ok │ ├── zipWith3.ok │ ├── blackscholes.ok │ ├── ceilfloormaxmin.ok │ ├── drop1dimtoMuch.apl │ ├── drop1dimtoMuch.ok │ ├── drop2DimNeg.ok │ ├── drop2DimtoMuch.ok │ ├── dyadic_transp.ok │ ├── reduceRank0.ok │ ├── reshape_empty.ok │ ├── sierpinski0.ok │ ├── first2.apl │ ├── innerLegrand5.3.ok │ ├── reshape_empty.apl │ ├── timespi.apl │ ├── first3.apl │ ├── rotateRank1.apl │ ├── snocRank1.apl │ ├── cons.apl │ ├── residue.ok │ ├── drop2Dim.apl │ ├── rot0err.ok │ ├── transpAPL.apl │ ├── rotateRank2.apl │ ├── .gitignore │ ├── drop2DimNeg.apl │ ├── drop2DimtoMuch.apl │ ├── drop3Dim.apl │ ├── snocRank2.apl │ ├── primes.apl │ ├── vowels.apl │ ├── cons1.apl │ ├── ceil.apl │ ├── red2.apl │ ├── residue.apl │ ├── vrev.ok │ ├── boolean.apl │ ├── scan.apl │ ├── gradeupdown.apl │ ├── zilde.apl │ ├── expd.apl │ ├── red.apl │ ├── fibpow.apl │ ├── slashbar.apl │ ├── mult.apl │ ├── compress.apl │ ├── rav.apl │ ├── spinpow.apl │ ├── sum35.apl │ ├── mult0.apl │ ├── replicate.apl │ ├── powtup.apl │ ├── sort.apl │ ├── vrev.apl │ ├── abcd.apl │ ├── sierpinski0.apl │ ├── circ.apl │ ├── mandel.apl │ ├── rot0err.apl │ ├── ceilfloormaxmin.apl │ ├── blackscholes.apl │ ├── innerLegrand5.3.apl │ ├── easter.apl │ ├── dtransp.apl │ ├── idx.apl │ ├── rot0.apl │ ├── primes0.apl │ ├── rot.apl │ ├── vrot.apl │ ├── drop.apl │ ├── take.apl │ ├── Makefile │ └── mandel.ok ├── benchmarks │ ├── size │ ├── time │ ├── life │ │ ├── dim.txt │ │ ├── gosper.rle │ │ ├── ex.rle │ │ ├── data.txt │ │ ├── Makefile │ │ ├── README.md │ │ ├── rle.sml │ │ └── 3enginecordershiprake.rle │ ├── matmul.in │ ├── .gitignore │ ├── matmul.apl │ ├── pi.apl │ ├── pi3.apl │ ├── Makefile │ ├── blackscholes.apl │ ├── matmul2.apl │ ├── eacheaster.apl │ ├── easter3000.apl │ ├── life.apl │ ├── easter.apl │ ├── lifein.apl │ ├── primes0.apl │ └── mandelbrot.apl ├── snoc.tail ├── zipwith.apl ├── integer.fut ├── integer_out.fut ├── snoc2dim.tail ├── snoc2dim2.tail ├── concat2matrices.apl ├── test2.tail ├── common.mk └── Test.hs ├── doc ├── code.png ├── primes.pdf ├── reduce.pdf ├── compilers.png ├── include │ ├── ku-en.pdf │ ├── nat-en.pdf │ ├── ku-farve.pdf │ ├── nat-farve.pdf │ ├── midvejsgantt.png │ └── natbio-farve.pdf ├── midvejsgantt.png ├── midvejsgantt2.png ├── midvejsgantt3.png ├── primes.tail ├── primes.fut ├── ku-template.tex ├── references.bib └── Midtvejsrapport.tex ├── futharksnippets ├── index.fut ├── reshape1lib.fut ├── drop.fut ├── transp2.fut ├── reshape2.fut ├── take3.fut ├── take2.fut └── transp3.fut ├── Makefile ├── tools ├── apl2futhark ├── apl2tail ├── apl2opencl ├── apl2python └── apl2pyopencl ├── src ├── Tail2Futhark │ ├── Prelude.hs │ ├── TAIL │ │ ├── AST.hs │ │ └── Parser.hs │ └── Futhark │ │ ├── AST.hs │ │ └── Pretty.hs ├── Options.hs └── Main.hs ├── .gitignore ├── .travis-setup.sh ├── stack.yaml ├── ops ├── tail2futhark.cabal ├── .travis.yml ├── README.md └── lib └── prelude.fut /.gitmodules: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/integer.tail: -------------------------------------------------------------------------------- 1 | 15 2 | -------------------------------------------------------------------------------- /tests/basic_tests/negi.apl: -------------------------------------------------------------------------------- 1 | -3 2 | -------------------------------------------------------------------------------- /tests/benchmarks/size: -------------------------------------------------------------------------------- 1 | 512 2 | -------------------------------------------------------------------------------- /tests/benchmarks/time: -------------------------------------------------------------------------------- 1 | 578 2 | -------------------------------------------------------------------------------- /tests/basic_tests/addi.apl: -------------------------------------------------------------------------------- 1 | 2 + 2 2 | -------------------------------------------------------------------------------- /tests/basic_tests/eqiFalse.apl: -------------------------------------------------------------------------------- 1 | 4=5 2 | -------------------------------------------------------------------------------- /tests/basic_tests/first.apl: -------------------------------------------------------------------------------- 1 | 2 | ⊃ 1 2 -------------------------------------------------------------------------------- /tests/basic_tests/gtiTrue.apl: -------------------------------------------------------------------------------- 1 | 5>4 2 | -------------------------------------------------------------------------------- /tests/basic_tests/iotaV.apl: -------------------------------------------------------------------------------- 1 | +/ ⍳ 5 2 | -------------------------------------------------------------------------------- /tests/basic_tests/ltei.apl: -------------------------------------------------------------------------------- 1 | 4 ≤ 3 2 | -------------------------------------------------------------------------------- /tests/basic_tests/maxi.apl: -------------------------------------------------------------------------------- 1 | 7 ⌈ 6 2 | -------------------------------------------------------------------------------- /tests/basic_tests/mini.apl: -------------------------------------------------------------------------------- 1 | 2 ⌊ 8 2 | -------------------------------------------------------------------------------- /tests/basic_tests/multi.apl: -------------------------------------------------------------------------------- 1 | 4×2 2 | -------------------------------------------------------------------------------- /tests/basic_tests/negd.apl: -------------------------------------------------------------------------------- 1 | -3.2 2 | -------------------------------------------------------------------------------- /tests/basic_tests/not0.apl: -------------------------------------------------------------------------------- 1 | ~(2=1) 2 | -------------------------------------------------------------------------------- /tests/basic_tests/not1.apl: -------------------------------------------------------------------------------- 1 | ~(1<3) 2 | -------------------------------------------------------------------------------- /tests/basic_tests/powi.apl: -------------------------------------------------------------------------------- 1 | 2 * 3 2 | -------------------------------------------------------------------------------- /tests/basic_tests/shape.ok: -------------------------------------------------------------------------------- 1 | 1.0 2 | -------------------------------------------------------------------------------- /tests/basic_tests/signd.apl: -------------------------------------------------------------------------------- 1 | × 7.3 2 | -------------------------------------------------------------------------------- /tests/basic_tests/signi.apl: -------------------------------------------------------------------------------- 1 | ×10 2 | -------------------------------------------------------------------------------- /tests/basic_tests/subi.apl: -------------------------------------------------------------------------------- 1 | 6-3 2 | -------------------------------------------------------------------------------- /tests/snoc.tail: -------------------------------------------------------------------------------- 1 | +/ 1 2 3 4 , 7 2 | -------------------------------------------------------------------------------- /tests/zipwith.apl: -------------------------------------------------------------------------------- 1 | +/ 1 2 3 + 4 5 6 2 | -------------------------------------------------------------------------------- /tests/basic_tests/abcd.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/addd.apl: -------------------------------------------------------------------------------- 1 | 2.3 + 4.5 2 | -------------------------------------------------------------------------------- /tests/basic_tests/addd.ok: -------------------------------------------------------------------------------- 1 | 6.800000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/addi.ok: -------------------------------------------------------------------------------- 1 | 4.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/cat.ok: -------------------------------------------------------------------------------- 1 | 7.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/catV.ok: -------------------------------------------------------------------------------- 1 | 21.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/ceil.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/circ.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/cons.ok: -------------------------------------------------------------------------------- 1 | 31.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/cons1.ok: -------------------------------------------------------------------------------- 1 | 17.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/divd.ok: -------------------------------------------------------------------------------- 1 | 6.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/divi.apl: -------------------------------------------------------------------------------- 1 | (4÷2) + 4 2 | -------------------------------------------------------------------------------- /tests/basic_tests/divi.ok: -------------------------------------------------------------------------------- 1 | 6.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/drop.ok: -------------------------------------------------------------------------------- 1 | 14.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/drop2.ok: -------------------------------------------------------------------------------- 1 | 6.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/each.ok: -------------------------------------------------------------------------------- 1 | 30.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/eachV.ok: -------------------------------------------------------------------------------- 1 | 52.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/easter.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/eqiTrue.apl: -------------------------------------------------------------------------------- 1 | 4 = 4 2 | -------------------------------------------------------------------------------- /tests/basic_tests/expd.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/first.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/first2.ok: -------------------------------------------------------------------------------- 1 | 2.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/first3.ok: -------------------------------------------------------------------------------- 1 | 3.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/gtdTrue.apl: -------------------------------------------------------------------------------- 1 | 3.4 > 1.2 2 | -------------------------------------------------------------------------------- /tests/basic_tests/gteiTrue.apl: -------------------------------------------------------------------------------- 1 | 3 ≥ 2 2 | -------------------------------------------------------------------------------- /tests/basic_tests/i2d.ok: -------------------------------------------------------------------------------- 1 | 5.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/idx.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/iotaV.ok: -------------------------------------------------------------------------------- 1 | 15.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/ltdTrue.apl: -------------------------------------------------------------------------------- 1 | 3.2 < 5.1 2 | -------------------------------------------------------------------------------- /tests/basic_tests/lted.apl: -------------------------------------------------------------------------------- 1 | 2.3 ≤ 3.3 2 | -------------------------------------------------------------------------------- /tests/basic_tests/lted.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/ltei.ok: -------------------------------------------------------------------------------- 1 | 0.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/lteiTrue.apl: -------------------------------------------------------------------------------- 1 | 4 ≤ 5 2 | -------------------------------------------------------------------------------- /tests/basic_tests/ltiTrue.apl: -------------------------------------------------------------------------------- 1 | 3 < 5 2 | -------------------------------------------------------------------------------- /tests/basic_tests/maxd.apl: -------------------------------------------------------------------------------- 1 | 2.3 ⌈ 6.4 2 | -------------------------------------------------------------------------------- /tests/basic_tests/maxd.ok: -------------------------------------------------------------------------------- 1 | 6.400000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/maxi.ok: -------------------------------------------------------------------------------- 1 | 7.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/mini.ok: -------------------------------------------------------------------------------- 1 | 2.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/muld.apl: -------------------------------------------------------------------------------- 1 | 3.4 × 1.2 2 | -------------------------------------------------------------------------------- /tests/basic_tests/muld.ok: -------------------------------------------------------------------------------- 1 | 4.080000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/multi.ok: -------------------------------------------------------------------------------- 1 | 8.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/negd.ok: -------------------------------------------------------------------------------- 1 | -3.200000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/negi.ok: -------------------------------------------------------------------------------- 1 | -3.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/not0.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/not1.ok: -------------------------------------------------------------------------------- 1 | 0.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/orTrue.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/ori.apl: -------------------------------------------------------------------------------- 1 | +/ 0 1 ∨ 1 1 2 | -------------------------------------------------------------------------------- /tests/basic_tests/ori.ok: -------------------------------------------------------------------------------- 1 | 2.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/powd.ok: -------------------------------------------------------------------------------- 1 | 8.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/powi.ok: -------------------------------------------------------------------------------- 1 | 8.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/powtup.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/rav.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/red.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/red2.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/rev.ok: -------------------------------------------------------------------------------- 1 | 4.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/rev2.ok: -------------------------------------------------------------------------------- 1 | 2.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/rot.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/rot0.ok: -------------------------------------------------------------------------------- 1 | 7.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/scan.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/signd.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/signi.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/sort.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/subd.apl: -------------------------------------------------------------------------------- 1 | 3.4 - 1.5 2 | -------------------------------------------------------------------------------- /tests/basic_tests/subd.ok: -------------------------------------------------------------------------------- 1 | 1.900000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/subi.ok: -------------------------------------------------------------------------------- 1 | 3.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/sum35.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/take.ok: -------------------------------------------------------------------------------- 1 | 19.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/take1.ok: -------------------------------------------------------------------------------- 1 | 6.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/take2.ok: -------------------------------------------------------------------------------- 1 | 5.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/vowels.ok: -------------------------------------------------------------------------------- 1 | 4.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/vrot.ok: -------------------------------------------------------------------------------- 1 | 3.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/zilde.ok: -------------------------------------------------------------------------------- 1 | 2.000000f64 2 | -------------------------------------------------------------------------------- /tests/benchmarks/life/dim.txt: -------------------------------------------------------------------------------- 1 | 15,15 2 | -------------------------------------------------------------------------------- /tests/basic_tests/andbTrue.apl: -------------------------------------------------------------------------------- 1 | (2=2) ∧ (3=3) 2 | -------------------------------------------------------------------------------- /tests/basic_tests/andbTrue.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/boolean.ok: -------------------------------------------------------------------------------- 1 | 2.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/compress.ok: -------------------------------------------------------------------------------- 1 | 8.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/divd.apl: -------------------------------------------------------------------------------- 1 | (4.0÷2.0) + 4 2 | -------------------------------------------------------------------------------- /tests/basic_tests/drop2.apl: -------------------------------------------------------------------------------- 1 | ⊃ 4 ↓ 2 3 4 5 6 2 | -------------------------------------------------------------------------------- /tests/basic_tests/drop2Dim.ok: -------------------------------------------------------------------------------- 1 | 26.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/drop3Dim.ok: -------------------------------------------------------------------------------- 1 | 100.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/dtransp.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/eqdFalse.apl: -------------------------------------------------------------------------------- 1 | 3.4 = 1.2 2 | -------------------------------------------------------------------------------- /tests/basic_tests/eqdFalse.ok: -------------------------------------------------------------------------------- 1 | 0.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/eqiFalse.ok: -------------------------------------------------------------------------------- 1 | 0.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/eqiTrue.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/fibpow.ok: -------------------------------------------------------------------------------- 1 | 232.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/firstV2.ok: -------------------------------------------------------------------------------- 1 | 3.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/firstV3.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/gradeupdown.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/gtdTrue.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/gtedFalse.apl: -------------------------------------------------------------------------------- 1 | 3.0 ≥ 3.2 2 | -------------------------------------------------------------------------------- /tests/basic_tests/gtedFalse.ok: -------------------------------------------------------------------------------- 1 | 0.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/gteiTrue.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/gtiTrue.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/ltdTrue.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/lteiTrue.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/ltiTrue.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/mult.ok: -------------------------------------------------------------------------------- 1 | 3025.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/mult0.ok: -------------------------------------------------------------------------------- 1 | 3025.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/orFalse.apl: -------------------------------------------------------------------------------- 1 | (2=1) ∨ (3=2) 2 | -------------------------------------------------------------------------------- /tests/basic_tests/orFalse.ok: -------------------------------------------------------------------------------- 1 | 0.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/orTrue.apl: -------------------------------------------------------------------------------- 1 | (2=1) ∨ (2=2) 2 | -------------------------------------------------------------------------------- /tests/basic_tests/powscl.apl: -------------------------------------------------------------------------------- 1 | ({ ⍵ + 1 }⍣3) 100 -------------------------------------------------------------------------------- /tests/basic_tests/powscl.ok: -------------------------------------------------------------------------------- 1 | 103.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/primes.ok: -------------------------------------------------------------------------------- 1 | 1060.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/primes0.ok: -------------------------------------------------------------------------------- 1 | 4.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/reduce2.ok: -------------------------------------------------------------------------------- 1 | 14.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/reduce3.ok: -------------------------------------------------------------------------------- 1 | 44.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/replicate.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/reshape.ok: -------------------------------------------------------------------------------- 1 | 6.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/reshape2.ok: -------------------------------------------------------------------------------- 1 | 8.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/rotateRank1.ok: -------------------------------------------------------------------------------- 1 | 3.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/rotateRank2.ok: -------------------------------------------------------------------------------- 1 | 3.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/slashbar.ok: -------------------------------------------------------------------------------- 1 | 405.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/snocRank1.ok: -------------------------------------------------------------------------------- 1 | 15.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/snocRank2.ok: -------------------------------------------------------------------------------- 1 | 176.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/spinpow.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/take1neg.ok: -------------------------------------------------------------------------------- 1 | 25.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/timespi.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/transp2.ok: -------------------------------------------------------------------------------- 1 | 6.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/transp3.ok: -------------------------------------------------------------------------------- 1 | 8.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/transpAPL.ok: -------------------------------------------------------------------------------- 1 | 21.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/xorbTrue.apl: -------------------------------------------------------------------------------- 1 | (3=3) ≠ (4=1) 2 | -------------------------------------------------------------------------------- /tests/basic_tests/xorbTrue.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/zipWith.ok: -------------------------------------------------------------------------------- 1 | 21.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/zipWith2.ok: -------------------------------------------------------------------------------- 1 | 36.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/zipWith3.ok: -------------------------------------------------------------------------------- 1 | 136.000000f64 2 | -------------------------------------------------------------------------------- /tests/benchmarks/matmul.in: -------------------------------------------------------------------------------- 1 | [512] 2 | [512] 3 | -------------------------------------------------------------------------------- /tests/integer.fut: -------------------------------------------------------------------------------- 1 | fun RealT main() = 2 | 15 -------------------------------------------------------------------------------- /tests/integer_out.fut: -------------------------------------------------------------------------------- 1 | fun RealT main() = 2 | 15 -------------------------------------------------------------------------------- /tests/basic_tests/blackscholes.ok: -------------------------------------------------------------------------------- 1 | 5.348365f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/ceilfloormaxmin.ok: -------------------------------------------------------------------------------- 1 | 1.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/drop1dimtoMuch.apl: -------------------------------------------------------------------------------- 1 | ⊃ +/ 8 ↓ ⍳ 6 2 | -------------------------------------------------------------------------------- /tests/basic_tests/drop1dimtoMuch.ok: -------------------------------------------------------------------------------- 1 | 0.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/drop2DimNeg.ok: -------------------------------------------------------------------------------- 1 | 10.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/drop2DimtoMuch.ok: -------------------------------------------------------------------------------- 1 | 0.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/dyadic_transp.ok: -------------------------------------------------------------------------------- 1 | 2.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/reduceRank0.ok: -------------------------------------------------------------------------------- 1 | 21.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/reshape_empty.ok: -------------------------------------------------------------------------------- 1 | 3.000000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/sierpinski0.ok: -------------------------------------------------------------------------------- 1 | 243.000000f64 2 | -------------------------------------------------------------------------------- /tests/benchmarks/.gitignore: -------------------------------------------------------------------------------- 1 | *.tail 2 | *.fut 3 | fut_* -------------------------------------------------------------------------------- /tests/snoc2dim.tail: -------------------------------------------------------------------------------- 1 | ⊃ ((2 2 ⍴ (4 3 2 1)) , 7) 2 | -------------------------------------------------------------------------------- /tests/snoc2dim2.tail: -------------------------------------------------------------------------------- 1 | ⊃ ((2 2 ⍴ (4 3 2 1)) , 7 5) 2 | -------------------------------------------------------------------------------- /tests/basic_tests/first2.apl: -------------------------------------------------------------------------------- 1 | x ← 2 2 ⍴ 2 3 4 5 2 | ⊃ x 3 | -------------------------------------------------------------------------------- /tests/basic_tests/innerLegrand5.3.ok: -------------------------------------------------------------------------------- 1 | 27190.400000f64 2 | -------------------------------------------------------------------------------- /tests/basic_tests/reshape_empty.apl: -------------------------------------------------------------------------------- 1 | +/0 0 0=3⍴⍳(1-1) 2 | -------------------------------------------------------------------------------- /tests/basic_tests/timespi.apl: -------------------------------------------------------------------------------- 1 | 0.000001>|3.141592-(○1) 2 | -------------------------------------------------------------------------------- /tests/basic_tests/first3.apl: -------------------------------------------------------------------------------- 1 | x ← 2 2 2 ⍴ 3 4 5 6 2 | ⊃ x 3 | -------------------------------------------------------------------------------- /tests/basic_tests/rotateRank1.apl: -------------------------------------------------------------------------------- 1 | y ← 2 ⌽ 1 2 3 4 2 | ⊃ y 3 | -------------------------------------------------------------------------------- /tests/basic_tests/snocRank1.apl: -------------------------------------------------------------------------------- 1 | y ← 1 2 3 , 9 2 | ⊃ +/ y 3 | -------------------------------------------------------------------------------- /tests/basic_tests/cons.apl: -------------------------------------------------------------------------------- 1 | a ← ⊃ ⍴ 1 2 3 2 | +/ a, ⍳ 7 ⍝ --> 31 -------------------------------------------------------------------------------- /tests/basic_tests/residue.ok: -------------------------------------------------------------------------------- 1 | [2i32, -2i32, 4i32, -2i32, 5i32] 2 | -------------------------------------------------------------------------------- /tests/basic_tests/drop2Dim.apl: -------------------------------------------------------------------------------- 1 | x ← 2 4 ⍴ ⍳ 8 2 | y ← 1 ↓ x 3 | ⊃ +/ y 4 | -------------------------------------------------------------------------------- /tests/basic_tests/rot0err.ok: -------------------------------------------------------------------------------- 1 | [1i32, 2i32, 5i32, 6i32, 9i32, 10i32] 2 | -------------------------------------------------------------------------------- /tests/basic_tests/transpAPL.apl: -------------------------------------------------------------------------------- 1 | x←⍳6 2 | y ← 2 3 ⍴ x 3 | +/ +/ ⍉ y 4 | -------------------------------------------------------------------------------- /tests/basic_tests/rotateRank2.apl: -------------------------------------------------------------------------------- 1 | y ← 2 3 4 ⍴ ⍳ 8 2 | x ← 2 ⌽ y 3 | ⊃ x 4 | -------------------------------------------------------------------------------- /tests/concat2matrices.apl: -------------------------------------------------------------------------------- 1 | x ← 2 4 ⍴ ⍳ 8 2 | y ← 11 12 3 | z ← x , y 4 | 0 5 | -------------------------------------------------------------------------------- /doc/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henrikurms/tail2futhark/HEAD/doc/code.png -------------------------------------------------------------------------------- /tests/basic_tests/.gitignore: -------------------------------------------------------------------------------- 1 | *.res 2 | *.resopencl 3 | *~ 4 | *.fut 5 | fut_* 6 | -------------------------------------------------------------------------------- /tests/basic_tests/drop2DimNeg.apl: -------------------------------------------------------------------------------- 1 | x ← 2 4 ⍴ ⍳ 8 2 | y ← (-1) ↓ x 3 | ⊃ +/ y 4 | -------------------------------------------------------------------------------- /tests/basic_tests/drop2DimtoMuch.apl: -------------------------------------------------------------------------------- 1 | x ← 2 4 ⍴ ⍳ 8 2 | y ← 3 ↓ x 3 | +/ +/ y 4 | -------------------------------------------------------------------------------- /tests/basic_tests/drop3Dim.apl: -------------------------------------------------------------------------------- 1 | x ← 2 2 4 ⍴ ⍳ 16 2 | y ← 1 ↓ x 3 | ⊃ +/ +/ y 4 | -------------------------------------------------------------------------------- /tests/basic_tests/snocRank2.apl: -------------------------------------------------------------------------------- 1 | x ← 2 2 ⍴ 2 3 4 5 2 | y ← x , 6 7 3 | +/ ×/ y 4 | -------------------------------------------------------------------------------- /doc/primes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henrikurms/tail2futhark/HEAD/doc/primes.pdf -------------------------------------------------------------------------------- /doc/reduce.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henrikurms/tail2futhark/HEAD/doc/reduce.pdf -------------------------------------------------------------------------------- /tests/basic_tests/primes.apl: -------------------------------------------------------------------------------- 1 | A←1↓⍳100 2 | primes ← (1=+⌿0=A∘.|A)/A 3 | 4 | +/ primes -------------------------------------------------------------------------------- /doc/compilers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henrikurms/tail2futhark/HEAD/doc/compilers.png -------------------------------------------------------------------------------- /tests/basic_tests/vowels.apl: -------------------------------------------------------------------------------- 1 | 2 | vowels ← { +/+/⍵ ∘.= 'AEIOUaeiou' } 3 | 4 | vowels'APL is Cool' -------------------------------------------------------------------------------- /doc/include/ku-en.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henrikurms/tail2futhark/HEAD/doc/include/ku-en.pdf -------------------------------------------------------------------------------- /doc/include/nat-en.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henrikurms/tail2futhark/HEAD/doc/include/nat-en.pdf -------------------------------------------------------------------------------- /doc/midvejsgantt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henrikurms/tail2futhark/HEAD/doc/midvejsgantt.png -------------------------------------------------------------------------------- /doc/midvejsgantt2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henrikurms/tail2futhark/HEAD/doc/midvejsgantt2.png -------------------------------------------------------------------------------- /doc/midvejsgantt3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henrikurms/tail2futhark/HEAD/doc/midvejsgantt3.png -------------------------------------------------------------------------------- /doc/include/ku-farve.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henrikurms/tail2futhark/HEAD/doc/include/ku-farve.pdf -------------------------------------------------------------------------------- /tests/basic_tests/cons1.apl: -------------------------------------------------------------------------------- 1 | x ← 1 2 3 2 | y ← 3 2 ⍴ 9 8 7 6 5 4 3 | z ← x , y 4 | q ← 1 ↑ y 5 | ⊃ +/ q 6 | -------------------------------------------------------------------------------- /doc/include/nat-farve.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henrikurms/tail2futhark/HEAD/doc/include/nat-farve.pdf -------------------------------------------------------------------------------- /tests/basic_tests/ceil.apl: -------------------------------------------------------------------------------- 1 | 2 | a ← ⌈ 3.2 2.8 ¯2.3 0.0 2.0 ¯1.7 3 | 4 | T1 ← 6=+/a ⍝ --> 6 5 | 6 | T1 -------------------------------------------------------------------------------- /doc/include/midvejsgantt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henrikurms/tail2futhark/HEAD/doc/include/midvejsgantt.png -------------------------------------------------------------------------------- /doc/include/natbio-farve.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henrikurms/tail2futhark/HEAD/doc/include/natbio-farve.pdf -------------------------------------------------------------------------------- /tests/basic_tests/red2.apl: -------------------------------------------------------------------------------- 1 | a ← 4 5 ⍴ ⍳ 20 2 | b ← ⍳ 3 3 | c ← b ∘.= a 4 | v ← +/c 5 | 6 | T ← ∧/(⍴v)=3 4 7 | T 8 | -------------------------------------------------------------------------------- /futharksnippets/index.fut: -------------------------------------------------------------------------------- 1 | 2 | fun [[int]] main() = 3 | let x = [2,3] in 4 | reshape((x[0],x[1]),[1,2,3,4,5,6]) 5 | -------------------------------------------------------------------------------- /tests/basic_tests/residue.apl: -------------------------------------------------------------------------------- 1 | 2 | X ← 3 ¯5 6 ¯3 0 | 29 43 ¯14 ¯14 5 3 | 4 | ⎕ ← X ⍝ → [5](2,-2,4,-2,5) 5 | 6 | 0 7 | -------------------------------------------------------------------------------- /tests/basic_tests/vrev.ok: -------------------------------------------------------------------------------- 1 | [[13i32, 3i32, 2i32, 1i32], [8i32, 9i32, 0i32, 1i32], [4i32, 5i32, 6i32, 7i32], [0i32, 1i32, 2i32, 3i32]] 2 | -------------------------------------------------------------------------------- /tests/basic_tests/boolean.apl: -------------------------------------------------------------------------------- 1 | 2 | a ← (0 ∧ 1) + (1 ∨ 0) 3 | b ← (1 ⍲ 0) 4 | c ← ~ b 5 | d ← (1 ⍱ 0) 6 | ⍝ e ← 1 2 ∈ 1 3 4 7 | a + b + c + d 8 | -------------------------------------------------------------------------------- /tests/basic_tests/scan.apl: -------------------------------------------------------------------------------- 1 | 2 | V ← +\ ⍳5 3 | 4 | T1 ← ∧/V=1 3 6 10 15 5 | 6 | A ← +\ 3 4 ⍴ ⍳ 12 7 | 8 | T2 ← ∧/∧/A=3 4 ⍴ 1 3 6 10 5 11 18 26 9 19 30 42 9 | 10 | ∧/ T1 T2 -------------------------------------------------------------------------------- /tests/basic_tests/gradeupdown.apl: -------------------------------------------------------------------------------- 1 | 2 | v ← 83 1 4 99 33 0 6 4 5 3 | r1 ← ⍋v 4 | T1 ← ∧/r1=6 2 3 8 9 7 5 1 4 5 | 6 | r2 ← ⍒v 7 | T2 ← ∧/r2=4 1 5 7 9 3 8 2 6 8 | 9 | ∧/ T1 T2 10 | -------------------------------------------------------------------------------- /tests/basic_tests/zilde.apl: -------------------------------------------------------------------------------- 1 | 2 | A1 ← 3 4 ⍴ ⍳ 12 3 | Z1 ← 0 ↑ A1 4 | T1 ← ∧/(⍴ Z1)=0 4 5 | 6 | A2 ← ⍉ 3 4 5 ⍴ ⍳ 60 7 | Z2 ← 0 ↑ A2 8 | T2 ← ∧/(⍴ Z2)=0 4 3 9 | 10 | +/ T1 T2 11 | 12 | -------------------------------------------------------------------------------- /tests/basic_tests/expd.apl: -------------------------------------------------------------------------------- 1 | 2 | a ← 2 * 3 3 | 4 | T1 ← 8=a ⍝ --> [](8.0) 5 | 6 | test ← { 0.000001>|⍺-⍵ } 7 | 8 | a ← * 3 9 | 10 | T2 ← 20.085536 test a ⍝ --> e^3 =~= 20.085536 11 | 12 | ∧/ T1 T2 -------------------------------------------------------------------------------- /tests/basic_tests/red.apl: -------------------------------------------------------------------------------- 1 | 2 | v ← ⍳ 5 3 | x ← 0 ↑ v 4 | T1 ← 0=+/ x 5 | 6 | a ← 4 5 3 ⍴ ⍳ 60 7 | x ← +/ 0 ↑ a 8 | T2 ← ∧/0 5=⍴ x 9 | 10 | y ← +⌿ 0 ↑ a 11 | T3 ← ∧/∧/y=5 3 ⍴ 0 12 | 13 | ∧ / T1 T2 T3 14 | -------------------------------------------------------------------------------- /tests/basic_tests/fibpow.apl: -------------------------------------------------------------------------------- 1 | ⍝ Power allows us to calculate a Fibonacci series 2 | fibo ← { 3 | a ← ((⊃⍴⍵)⍴⍵) 4 | a,+/¯2↑a 5 | } 6 | 7 | fib ← {(fibo⍣⍵) 0 1} 8 | 9 | list ← fib 10 10 | 11 | +/ list ⍝ 232 -------------------------------------------------------------------------------- /tests/basic_tests/slashbar.apl: -------------------------------------------------------------------------------- 1 | 2 | a ← 2 3 ⍴ ⍳ 6 ⍝ 1 2 3 3 | ⍝ 4 5 6 4 | 5 | b ← +⌿ a ⍝ 5 7 9 6 | c ← +/ a ⍝ 6 15 7 | 8 | (×/b) + ×/c ⍝ 5 × 7 × 9 + 6 × 15 = 315 + 90 = 405 -------------------------------------------------------------------------------- /tests/basic_tests/mult.apl: -------------------------------------------------------------------------------- 1 | ⍝ Multiplication table 2 | ⍝ a × b scalar multiplication, "a times b" 3 | ⍝ ∘. is the "outer product" operator 4 | ⍝ A ∘.× B every item in A times every item in B 5 | b ← (⍳ 10) ∘.× ⍳ 10 6 | +/+/b -------------------------------------------------------------------------------- /tests/basic_tests/compress.apl: -------------------------------------------------------------------------------- 1 | a ← (0 1 0 1=1 1 1 1) / ⍳ 4 ⍝ --> 2 4 2 | 3 | b ← ⊃ ⍴ a ⍝ --> 2 4 | 5 | c ← +/a ⍝ --> 6 6 | 7 | b + c ⍝ --> 8 8 | -------------------------------------------------------------------------------- /tests/benchmarks/matmul.apl: -------------------------------------------------------------------------------- 1 | 2 | linspace ← { ((⍳⍵)-1) ÷ (⍵-1) } 3 | 4 | m ← ⎕ReadIntVecFile 'matrix' 5 | s ← ⎕ReadIntVecFile 'size' 6 | n ← ⊃ s 7 | ⍝ a ← (n n ⍴ ÷n) 8 | a ← (n n ⍴ ÷m) 9 | b ← ⍉ a 10 | c ← a +.× b 11 | ×/ +/ c 12 | -------------------------------------------------------------------------------- /tests/basic_tests/rav.apl: -------------------------------------------------------------------------------- 1 | 2 | A ← 2 3 ⍴ ⍳6 3 | V ← ⌽⍳5 4 | 5 | R1 ← ,⍉A ⍝ → 1 4 2 5 3 6 6 | T1 ← ∧/R1=1 4 2 5 3 6 7 | 8 | R2 ← ,V 9 | T2 ← ∧/R2=5 4 3 2 1 10 | 11 | ⍝ R3 ← ,4 12 | ⍝ T3 ← ∧/R3=1⍴4 13 | 14 | ∧ / T1 T2 -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | .PHONY: all 3 | all: 4 | stack build 5 | 6 | .PHONY: install 7 | install: 8 | stack install 9 | 10 | .PHONY: test 11 | test: 12 | make -C tests/basic_tests test 13 | 14 | .PHONY: clean 15 | clean: 16 | make -C tests/basic_tests clean 17 | -------------------------------------------------------------------------------- /tests/basic_tests/spinpow.apl: -------------------------------------------------------------------------------- 1 | ⍝ Power Operator example from Legrands "Mastering Dyalog APL", page 415 (first edition). 2 | 3 | mat ← 3 3 ⍴ 1 2 3 8 0 4 7 6 5 4 | 5 | Spin ← {⊖⍉⍵} 6 | 7 | x ← (Spin ⍣ 14) mat 8 | 9 | y ← x = Spin Spin mat 10 | 11 | ∧/∧/y 12 | -------------------------------------------------------------------------------- /tests/benchmarks/pi.apl: -------------------------------------------------------------------------------- 1 | 2 | linspace ← { ((⍳⍵)-1) ÷ (⍵-1) } 3 | 4 | ⍝ Compute pi 5 | m ← 40000 6 | n ← m×m 7 | d ← linspace m 8 | a ← { ⍵ × ⍵ } d 9 | b ← m m ⍴ a 10 | y ← +/+/ (1> (b + (⍉ b))) 11 | pi ← 4×y÷n 12 | ⍝ ⎕ ← pi 13 | pi 14 | ⍝ 0.1 > | pi - ○ 1 15 | -------------------------------------------------------------------------------- /tests/benchmarks/pi3.apl: -------------------------------------------------------------------------------- 1 | 2 | linspace ← { ((⍳⍵)-1) ÷ (⍵-1) } 3 | 4 | ⍝ Compute pi 5 | m ← 13722 6 | n ← m×m 7 | a ← linspace m 8 | b ← (n 1 ⍴ (m m ⍴ a)) , (n 1 ⍴ ⍉ (m m ⍴ a)) 9 | x ← +/1>+/b*2 10 | pi ← 4×x÷n 11 | ⍝ ⎕ ← pi 12 | pi 13 | ⍝ 0.1 > | pi - ○ 1 14 | -------------------------------------------------------------------------------- /tests/basic_tests/sum35.apl: -------------------------------------------------------------------------------- 1 | 2 | ⍝ Calculate the sum of all multiples of 3 or 5 below 1000 3 | 4 | f ← {+/⍵×(0=3|⍵)∨0=5|⍵} 5 | 6 | sumbelow ← {f⍳⍵-1} 7 | 8 | T1 ← 23=sumbelow 10 ⍝ → 23 9 | 10 | T2 ← 233168=sumbelow 1000 ⍝ → 233168 11 | 12 | ∧/ T1 T2 13 | -------------------------------------------------------------------------------- /tests/basic_tests/mult0.apl: -------------------------------------------------------------------------------- 1 | out ← { 2 | A ← ⍺ 3 | B ← ⍵ 4 | T ← (⊃(⍴⍴B))⌽⍳⊃⍴(⍴B),⍴A 5 | ⍝ T ← (⊃(⍴⍴B))⌽⍳⊃(⍴⍴B)+⍴⍴A 6 | x ← T ⍉ ((⍴B),(⍴A)) ⍴ A 7 | y ← ((⍴A),(⍴B)) ⍴ B 8 | z ← x ⍺⍺ y 9 | } 10 | 11 | res ← (⍳ 10) × out (⍳ 10) 12 | 13 | +/+/res ⍝ → [0](3025) -------------------------------------------------------------------------------- /tests/benchmarks/life/gosper.rle: -------------------------------------------------------------------------------- 1 | #N Gosper glider gun 2 | #C This was the first gun discovered. 3 | #C As its name suggests, it was discovered by Bill Gosper. 4 | x = 36, y = 9, rule = B3/S23 5 | 24bo$22bobo$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o$2o8bo3bob2o4b 6 | obo$10bo5bo7bo$11bo3bo$12b2o! -------------------------------------------------------------------------------- /tests/benchmarks/Makefile: -------------------------------------------------------------------------------- 1 | include ../common.mk 2 | 3 | APLFILES=$(wildcard *.apl) 4 | FUTEXECS=$(APLFILES:%.apl=fut_%) 5 | TLEXECS=$(APLFILES:%.apl=tail_%) 6 | 7 | .PHONY: all 8 | all: $(FUTEXECS) $(TLEXECS) 9 | 10 | clean: 11 | make -C life clean 12 | rm -f *~ *.fut *.tail tail_* fut_* 13 | -------------------------------------------------------------------------------- /tools/apl2futhark: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | apl_source=$1 4 | tail_source=${apl_source%.*}.tail 5 | futhark_source=${apl_source%.*}.fut 6 | 7 | shift 8 | 9 | apl2tail "$apl_source" 10 | if tail2futhark "$tail_source" "$@" > "$futhark_source"; then 11 | echo "Wrote file $futhark_source" 12 | fi 13 | -------------------------------------------------------------------------------- /tests/basic_tests/replicate.apl: -------------------------------------------------------------------------------- 1 | a ← ⍳ 4 2 | 3 | b ← a / a ⍝ --> 1 2 2 3 3 3 4 4 4 4 4 | T1 ← 30=+/ b ⍝ --> 30 5 | 6 | 7 | T2 ← ∧/'accdeee'=1 0 2 1 3 / 'abcde' ⍝ 'accdeee' 8 | 9 | T3 ← ∧/'acc eee'=1 0 2 ¯2 3 / 'abcde' ⍝ 'acc eee' 10 | 11 | T4 ← ∧/'aaaaa'=5/'a' 12 | 13 | ∧ / T1 T2 T3 T4 14 | -------------------------------------------------------------------------------- /futharksnippets/reshape1lib.fut: -------------------------------------------------------------------------------- 1 | 2 | fun [int] extend(int l, [int] x) = 3 | reshape((size(0,x) * (l/size(0,x)+1)),replicate(l/size(0,x)+1,x)) 4 | 5 | fun [int] takeLess(int l, [int] x) = 6 | let {v1,_} = split((l),x) in v1 7 | 8 | fun [int] reshape1int(int l, [int] x) = 9 | takeLess(l,extend(l,x)) 10 | 11 | -------------------------------------------------------------------------------- /tests/basic_tests/powtup.apl: -------------------------------------------------------------------------------- 1 | 2 | f ← { 3 | a1 ← ⍵[1] 4 | a2 ← ⍵[2] 5 | a3 ← ⍵[3] 6 | r1 ← (1 1) + a1 7 | r2 ← a2,'hej' 8 | (r1 r2 3) 9 | } 10 | 11 | res ← (f⍣3) ((2 3) 'asbc' 8) 12 | ⍝ res ← f (2 '') 13 | 14 | T1 ← ∧/res[1]=5 6 15 | T2 ← ∧/res[2]='asbchejhejhej' 16 | T3 ← res[3]=3 17 | 18 | ∧/T1 T2 T3 -------------------------------------------------------------------------------- /tests/basic_tests/sort.apl: -------------------------------------------------------------------------------- 1 | 2 | v ← 4 3 32 45 656 23 545 23 65 45 56 76 3 | 4 | r1 ← v[⍋v] 5 | T1 ← ∧/r1=3 4 23 23 32 45 45 56 65 76 545 656 6 | 7 | r2 ← v[⍒v] 8 | T2 ← ∧/r2=656 545 76 65 56 45 45 32 23 23 4 3 9 | 10 | r3 ← ⍋ 0 ↑ 2 3 34 2 11 | T3 ← ∧/r3=⍬ 12 | 13 | r4 ← ⍋ 1 ↑ 2 3 34 2 14 | T4 ← ∧/r4=1⍴1 15 | 16 | ∧/ T1 T2 T3 T4 -------------------------------------------------------------------------------- /tests/benchmarks/life/ex.rle: -------------------------------------------------------------------------------- 1 | #N 44P5H2V0 2 | #O Dean Hickerson 3 | #C The first 2c/5 spaceship to be discovered 4 | #C http://www.conwaylife.com/wiki/index.php?title=44P5H2V0 5 | x = 15, y = 11, rule = b3/s23 6 | 4bo5bo4b$3b3o3b3o3b$2bo2bo3bo2bo2b$b3o7b3ob$2bobo5bobo2b$4b2o3b2o4b$o 7 | 4bo3bo4bo$5bo3bo5b$2o3bo3bo3b2o$2bo2bo3bo2bo2b$4bo5bo! -------------------------------------------------------------------------------- /src/Tail2Futhark/Prelude.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE QuasiQuotes #-} 2 | {-# LANGUAGE TemplateHaskell #-} 3 | module Tail2Futhark.Prelude ( futharkPrelude ) where 4 | 5 | import Data.FileEmbed 6 | 7 | -- | A prelude prefixed to every generated Futhark program. 8 | futharkPrelude :: String 9 | futharkPrelude = $(embedStringFile "lib/prelude.fut") 10 | -------------------------------------------------------------------------------- /tests/basic_tests/vrev.apl: -------------------------------------------------------------------------------- 1 | 2 | ⍝ Reverse along first axis 3 | 4 | A ← ⊖ 13 ⍝ --> 13 5 | 6 | B ← ⊖ 1 2 3 A ⍝ --> 13 3 2 1 7 | 8 | x ← ⊖ 3 4 ⍴ ⍳ 10 ⍝ --> 9 10 1 2 9 | ⍝ 5 6 7 8 10 | ⍝ 1 2 3 4 11 | 12 | ⍝ C ← ⊖ ⍬ ⍝ --> [0]() 13 | 14 | ⎕ ← B ⍪ x - 1 15 | 16 | 0 -------------------------------------------------------------------------------- /tests/test2.tail: -------------------------------------------------------------------------------- 1 | let v0:52 = catV{[int],[30,22]}(iotaV(30),iotaV(22)) in 2 | let v2:63 = catV{[int],[11,52]}([b2iV(tt),2,23,3,4,5,344,6,7,7,5],eachV{[int,int],[52]}(fn v1:[int]0 => addi(5,v1),v0)) in 3 | i2d(reduce{[int],[0]}(fn v4:[int]0 => fn v5:[int]0 => maxi(v5,v4),0,dropV{[int],[60]}(3,eachV{[int,int],[63]}(fn v3:[int]0 => addi(5,v3),v2)))) 4 | -------------------------------------------------------------------------------- /tests/benchmarks/life/data.txt: -------------------------------------------------------------------------------- 1 | 0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0 2 | -------------------------------------------------------------------------------- /tests/basic_tests/abcd.apl: -------------------------------------------------------------------------------- 1 | 2 | elements ← 'ABCD' 3 | 4 | samples ← 8 6 ⍴ 'CCCAACBAADABCAACDCACDDBCDDCCCBADCBCCCACCCBCCBACC' 5 | 6 | X ← elements ∘.= samples 7 | 8 | Y ← ∨/ X 9 | ⍝ ⎕← 'Result:' 10 | R← ∧⌿∨/ X ⍝ --> [8](0,0,0,1,0,1,0,0) 11 | 12 | T ← ∧/R=0 0 0 1 0 1 0 0 13 | 14 | ⍝ {∧/⍵}¨∨/{⍵ = elements}¨samples 15 | 16 | ⍝ T 17 | 18 | T 19 | -------------------------------------------------------------------------------- /futharksnippets/drop.fut: -------------------------------------------------------------------------------- 1 | fun [int] dropV(int l, [int] x) = 2 | if 0 <= l then 3 | if l <= size(0,x) then 4 | let {v1,v2} = split(l,x) in v2 5 | else 6 | empty(int) 7 | else 8 | if -l <= size(0,x) then 9 | let {v1,v2} = split(size(0,x)+l,x) in v1 10 | else 11 | empty(int) 12 | 13 | fun [int] main() = 14 | dropV(-7,[1,2,3,4,5,6,7,8,9]) 15 | -------------------------------------------------------------------------------- /tests/basic_tests/sierpinski0.apl: -------------------------------------------------------------------------------- 1 | ⍝ 2 | ⍝ * if S is the triangle of rank n, then rank n+1 would be 3 | ⍝ the two-dimensional catenation: 4 | ⍝ S 0 5 | ⍝ S S 6 | ⍝ where "0" is an all-blank matrix same size as S. 7 | 8 | f ← {(⍵,(⍴⍵)⍴0)⍪⍵,⍵} 9 | ⍝ S ← {(f⍣⍵) 1 1 ⍴ 1} 10 | ⍝ S 5 11 | a ← 1 1 ⍴ 1 12 | a ← f a 13 | a ← f a 14 | a ← f a 15 | a ← f a 16 | a ← f a 17 | 18 | +/+/a ⍝ ---> 243 19 | -------------------------------------------------------------------------------- /tests/basic_tests/circ.apl: -------------------------------------------------------------------------------- 1 | test ← { 0.000001>|⍺-⍵ } 2 | 3 | T1 ← 3.141592 test (○1) 4 | 5 | T2 ← 9.424777 test (○3) 6 | 7 | T3 ← 9.738937 test (○3.1) 8 | 9 | ⍝ ⎕ ← 'Sin 3.14' 10 | T4 ← 0.001592 test (1 ○ 3.14) 11 | 12 | ⍝ ⎕ ← 'Cos 3.14' 13 | T5 ← ¯0.999998 test (2 ○ 3.14) 14 | 15 | ⍝ ⎕ ← 'Tan 3.14' 16 | T6 ← ¯0.001592 test (3 ○ 3.14) 17 | 18 | ⍝ ⎕ ← '2+pi^2' 19 | T7 ← 11.864600 test (2 + ○ 3.14) 20 | 21 | ∧/ T1 T2 T3 T4 T5 T6 T7 -------------------------------------------------------------------------------- /tools/apl2tail: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ $# -ne 1 ]; then 4 | echo "Usage: $0 " 5 | exit 1 6 | fi 7 | 8 | if ! [ "$TAIL_ROOT" ]; then 9 | echo '$TAIL_ROOT must point to a checkout of the apltail repository.' 10 | exit 1 11 | fi 12 | 13 | apl_source=$1 14 | tail_source=${apl_source%.*}.tail 15 | 16 | TAIL_PRELUDE=${TAIL_ROOT}/lib/prelude.apl 17 | 18 | aplt -p_types -s_tail -c -o "$tail_source" $TAIL_PRELUDE "$apl_source" 19 | -------------------------------------------------------------------------------- /tests/basic_tests/mandel.apl: -------------------------------------------------------------------------------- 1 | ⍝ Mandelbrot one-liner: 2 | 3 | ⍝ Compared to Dyalog APL, additional parentheses are needed around 4 | ⍝ bindings (←) and around the power operator (⍣). Moreover, the 5 | ⍝ function parameter to the power operator needs to be monadic. 6 | 7 | ⎕ ← ' #'[1+9>|({m+⍵×⍵}⍣9)(m←¯3×.7j.5-⍉a∘.+0j1×(a←(1+⍳n+1)÷(n←28)))] 8 | 9 | ⍝ And one that uses trains, which does not work...: 10 | ⍝ ⎕ ← ' #'[1+9>|m∘(2*⍨+)⍣9⊢(m←¯3×.7j.5-⍉a∘.+0j1×(a←(1+⍳n+1)÷(n←98)))] 11 | 12 | 0 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | aplacc/tests/newtests/*.out 2 | aplacc/tests/newtests/*.fut 3 | doc/*.aux 4 | doc/*.log 5 | doc/*.pdf 6 | doc/*.toc 7 | doc/*.bbl 8 | doc/*.blg 9 | tests/Test 10 | *.fout 11 | *.out 12 | benchmarks/* 13 | ! benchmarks/*.apl 14 | ! benchmarks/Makefile 15 | *.c 16 | 17 | *.pdf 18 | *.log 19 | *.aux 20 | *.synctex.gz 21 | 22 | *.swp 23 | .DS_Store 24 | 25 | dist 26 | cabal-dev 27 | *.o 28 | *.hi 29 | *.chi 30 | *.chs.h 31 | .virtualenv 32 | .hsenv 33 | .cabal-sandbox/ 34 | cabal.sandbox.config 35 | cabal.config 36 | 37 | -------------------------------------------------------------------------------- /tests/basic_tests/rot0err.apl: -------------------------------------------------------------------------------- 1 | ⍝ Rotate along the last axis as in (1 ⌽ A) 2 | 3 | A ← 3 4 ⍴ ⍳ 12 4 | 5 | TA ← ⍉ A ⍝ --> 1 5 9 6 | ⍝ 2 6 10 7 | ⍝ 3 7 11 8 | ⍝ 4 8 12 9 | 10 | M6 ← 2 ↑ TA ⍝ --> 1 5 9 11 | ⍝ 2 6 10 12 | 13 | M7 ← ⍉ M6 ⍝ --> 1 2 14 | ⍝ 5 6 15 | ⍝ 9 10 16 | ⎕ ← 6 ⍴ M7 17 | 18 | 0 -------------------------------------------------------------------------------- /tests/basic_tests/ceilfloormaxmin.apl: -------------------------------------------------------------------------------- 1 | 2 | a ← ⌈ 3.2 2.8 ¯2.3 0.0 2.0 ¯1.7 3 | b ← ⌊ 3.2 2.8 ¯2.3 0.0 2.0 ¯1.7 4 | 5 | T1 ← 6=+/ a ⍝ --> 6 6 | T2 ← 2=+/ b ⍝ --> 2 7 | 8 | c ← 2.0 ⌈ 3.2 2.8 ¯2.3 0.0 2.0 ¯1.7 9 | 10 | T3 ← 14=+/ c ⍝ --> 14.0 11 | 12 | d ← 2.0 ⌊ 3.2 2.8 ¯2.3 0.0 2.0 ¯1.7 13 | 14 | T4 ← 2=+/ d ⍝ --> 2.0 15 | 16 | ⍝ boolean promotion 17 | T5 ← 0=0 ⌊ 1 ⍝ --> 0 18 | T6 ← 1=0 ⌈ 1 ⍝ --> 1 19 | T7 ← 1=⌊ 1 ⍝ --> 1 20 | T8 ← 0=⌊ 0 ⍝ --> 0 21 | 22 | ∧/T1 T2 T3 T4 T5 T6 T7 T8 23 | -------------------------------------------------------------------------------- /doc/primes.tail: -------------------------------------------------------------------------------- 1 | let v1:8 = dropV{[int],[8]}(1,iotaV(9)) in 2 | let v7:[int]2 = transp{[int],[2]}(reshape{[int],[1,2]}([8,8],v1)) in 3 | let v8:[int]2 = reshape{[int],[1,2]}([8,8],v1) in 4 | let v11:[int]2 = zipWith{[int,int,int],[2]}(resi,v7,v8) in 5 | let v13:[bool]2 = each{[int,bool],[2]}(fn v12:[int]0 => eqi(0,v12),v11) in 6 | let v18:[int]1 = transp{[int],[1]}(reduce{[int],[1]}(addi,0,each{[bool,int],[2]}(b2i,transp{[bool],[2]}(v13)))) in 7 | let v20:[bool]1 = each{[int,bool],[1]}(fn v19:[int]0 => eqi(1,v19),v18) in 8 | let v24:[int]0 = reduce{[int],[0]}(addi,0,each{[bool,int],[1]}(b2i,v20)) in 9 | i2d(v24) 10 | -------------------------------------------------------------------------------- /futharksnippets/transp2.fut: -------------------------------------------------------------------------------- 1 | fun [int] takeV(int l, [int] x) = 2 | if 0 <= l then 3 | if l <= size(0,x) then 4 | let {v1,v2} = split(l,x) in v1 5 | else 6 | concat(x,replicate(l - size(0,x),0)) 7 | else 8 | if -l <= size(0,x) then 9 | let {v1,v2} = split(size(0,x)+l,x) in v2 10 | else 11 | concat(replicate(-(size(0,x)+l),0),x) 12 | 13 | 14 | fun [[int]] take2(int l, [[int]] x) = 15 | reshape((if l <= 0 then (-l) else l,size(1,x)), takeV(l*size(1,x), reshape((size(0,x)*size(1,x)),x))) 16 | 17 | fun [[int]] main() = 18 | rearrange((1,0),[[1,2,3],[4,5,6],[7,8,9]]) 19 | -------------------------------------------------------------------------------- /futharksnippets/reshape2.fut: -------------------------------------------------------------------------------- 1 | fun [int] extend(int l, [int] x) = 2 | reshape((size(0,x) * (l/size(0,x)+1)),replicate(l/size(0,x)+1,x)) 3 | 4 | fun [int] takeLess(int l, [int] x) = 5 | let {v1,_} = split((l),x) in v1 6 | 7 | fun [int] reshape1(int l, [int] x) = 8 | takeLess(l,extend(l,x)) 9 | 10 | fun [[int]] reshape2(int dim1, int dim2, [[int]] x) = 11 | reshape((dim1,dim2), reshape1(dim1*dim2,reshape((size(0,x)*size(1,x)),x))) 12 | 13 | fun [[int]] main() = 14 | reshape2(4,4,[[1,2,3],[4,5,6]]) 15 | 16 | 17 | // replicate(a,x) er stort nok 18 | 19 | // |replicate(a,x)| >= l 20 | 21 | // a * |x| >= l 22 | 23 | // a >= l/|x| 24 | 25 | 26 | -------------------------------------------------------------------------------- /futharksnippets/take3.fut: -------------------------------------------------------------------------------- 1 | fun [int] takeV(int l, [int] x) = 2 | if 0 <= l then 3 | if l <= size(0,x) then 4 | let {v1,v2} = split(l,x) in v1 5 | else 6 | concat(x,replicate(l - size(0,x),0)) 7 | else 8 | if -l <= size(0,x) then 9 | let {v1,v2} = split(size(0,x)+l,x) in v2 10 | else 11 | concat(replicate(-(size(0,x)+l),0),x) 12 | 13 | 14 | fun [[[int]]] take3(int l, [[[int]]] x) = 15 | reshape((if l <= 0 then (-l) else l,size(1,x),size(2,x)), takeV(l*size(1,x)*size(2,x), reshape((size(0,x)*size(1,x)*size(2,x)),x))) 16 | 17 | fun [[[int]]] main() = 18 | take3(-3,[[[1,2],[3,4]],[[5,6],[7,8]]]) 19 | -------------------------------------------------------------------------------- /futharksnippets/take2.fut: -------------------------------------------------------------------------------- 1 | 2 | fun [int] takeV(int l, [int] x) = 3 | if 0 <= l then 4 | if l <= size(0,x) then 5 | let {v1,v2} = split((l),x) in v1 6 | else 7 | concat(x,replicate(l - size(0,x),0)) 8 | else 9 | if -l <= size(0,x) then 10 | let {v1,v2} = split((size(0,x)+l),x) in v2 11 | else 12 | concat(replicate(l - size(0,x),0),x) 13 | 14 | 15 | fun int abs(int x) = 16 | if x <= 0 then -x else x 17 | 18 | fun [[int]] take2(int l, [[int]] x) = 19 | reshape(((abs(l)),size(1,x)), takeV(l*size(1,x), reshape((size(0,x)*size(1,x)),x))) 20 | 21 | fun [[int]] main() = 22 | take2(-2,[[1,2,3],[4,5,6],[7,8,9]]) 23 | -------------------------------------------------------------------------------- /futharksnippets/transp3.fut: -------------------------------------------------------------------------------- 1 | fun [int] takeV(int l, [int] x) = 2 | if 0 <= l then 3 | if l <= size(0,x) then 4 | let {v1,v2} = split((l),x) in v1 5 | else 6 | concat(x,replicate(l - size(0,x),0)) 7 | else 8 | if -l <= size(0,x) then 9 | let {v1,v2} = split((size(0,x)+l),x) in v2 10 | else 11 | concat(replicate(-(size(0,x)+l),0),x) 12 | 13 | 14 | fun [[[int]]] take3(int l, [[[int]]] x) = 15 | reshape((if l <= 0 then (-l) else l,size(1,x),size(2,x)), takeV(l*size(1,x)*size(2,x), reshape((size(0,x)*size(1,x)*size(2,x)),x))) 16 | 17 | fun [[[int]]] main() = 18 | rearrange((2,1,0),[[[1,2],[3,4]],[[5,6],[7,8]]]) 19 | -------------------------------------------------------------------------------- /tests/benchmarks/blackscholes.apl: -------------------------------------------------------------------------------- 1 | CND ← { 2 | X ← ⍵ 3 | a ← 0.31938153 ¯0.356563782 1.781477937 ¯1.821255978 1.330274429 4 | 5 | l ← |X 6 | k ← ÷1+0.2316419×l 7 | w ← 1 - (÷((2×(○1))⋆0.5)) × (⋆-(l×l)÷2) × (a +.× (k⋆⍳5)) 8 | 9 | ((|0⌊×X)×(1-w))+(1-|0⌊×X)×w 10 | } 11 | 12 | ⍝ S - current price 13 | ⍝ X - strike price 14 | ⍝ T - expiry in years 15 | ⍝ r - riskless interest rate 16 | ⍝ v - volatility 17 | 18 | S ← 60 19 | X ← 65 20 | T ← 1 21 | r ← 0.1 22 | v ← 0.2 23 | 24 | d1 ← ((⍟S÷X)+(r+(v⋆2)÷2)×T)÷(v×T⋆0.5) 25 | d2 ← d1-v×T⋆0.5 26 | 27 | ⍝ Call price 28 | callPrice ← (S×CND(d1))-(X×⋆-r×T)×CND(d2) 29 | 30 | ⍝ Put price (not tested) 31 | ⍝ putPrice ← (X×⋆-r×T)×CND(-d2)-S×CND(-d1) 32 | -------------------------------------------------------------------------------- /tests/benchmarks/life/Makefile: -------------------------------------------------------------------------------- 1 | EXAMPLES=ex.rle gosper.rle 3enginecordershiprake.rle 2 | FUTINS=$(EXAMPLES:%.rle=%.futin) 3 | FUTOUTS=$(EXAMPLES:%.rle=%.futout) 4 | FUTSEES=$(EXAMPLES:%.rle=%.futsee) 5 | 6 | all: rle $(FUTINS) $(FUTOUTS) 7 | 8 | rle: rle.sml 9 | mlkit -o rle rle.sml 10 | 11 | clean: 12 | rm -rf MLB *~ rle *.futin *.futout *.futsee 13 | 14 | 15 | %.futin: %.rle rle 16 | ./rle --flat < $< > $@ 17 | 18 | %.futout: %.futin 19 | ../fut_lifein < $< >$@ 20 | 21 | %.futsee: %.futout Makefile 22 | sed 's/111i32/o/g' < $< | \ 23 | sed 's/32i32/_/g' | \ 24 | sed 's/\[//g' | \ 25 | tr ']' '\n' | \ 26 | sed 's/, //g' > $@ 27 | 28 | include ../../common.mk 29 | 30 | withaplt: 31 | $(APLT) $(PRELUDE) ../lifein.apl 32 | -------------------------------------------------------------------------------- /tests/basic_tests/blackscholes.apl: -------------------------------------------------------------------------------- 1 | CND ← { 2 | X ← ⍵ 3 | a ← 0.31938153 ¯0.356563782 1.781477937 ¯1.821255978 1.330274429 4 | 5 | l ← |X 6 | k ← ÷1+0.2316419×l 7 | w ← 1 - (÷(2×(○1))⋆0.5) × (⋆-l×l÷2) × (a +.× k⋆⍳5) 8 | 9 | ⍝ This magic sets w = 1-w if x<0 10 | ((|0⌊×X)×(1-w))+(1-|0⌊×X)×w 11 | } 12 | 13 | ⍝ S - current price 14 | ⍝ X - strike price 15 | ⍝ T - expiry in years 16 | ⍝ r - riskless interest rate 17 | ⍝ v - volatility 18 | 19 | S ← 60 20 | X ← 65 21 | T ← 1 22 | r ← 0.1 23 | v ← 0.2 24 | 25 | d1 ← ((⍟S÷X)+(r+(v⋆2)÷2)×T)÷(v×T⋆0.5) 26 | d2 ← d1-v×T⋆0.5 27 | 28 | ⍝ Call price 29 | callPrice ← (S×CND(d1))-(X×⋆-r×T)×CND(d2) 30 | 31 | ⍝ Put price (not tested) 32 | ⍝ putPrice ← (X×⋆-r×T)×CND(-d2)-S×CND(-d1) -------------------------------------------------------------------------------- /tests/benchmarks/matmul2.apl: -------------------------------------------------------------------------------- 1 | inner ← { 2 | WA ← (1↓⍴⍵),⍴⍺ 3 | KA ← (⊃⍴⍴⍺)-1 4 | VA ← ⍳ ⊃ ⍴WA 5 | ZA ← (KA⌽¯1↓VA),¯1↑VA 6 | TA ← ZA⍉WA⍴⍺ ⍝ Replicate, transpose 7 | WB ← (¯1↓⍴⍺),⍴⍵ 8 | KB ← ⊃ ⍴⍴⍺ 9 | VB ← ⍳ ⊃ ⍴WB 10 | ZB0 ← (-KB) ↓ KB ⌽ ⍳(⊃⍴VB) 11 | ZB ← (¯1↓(⍳ KB)),ZB0,KB 12 | TB ← ZB⍉WB⍴⍵ ⍝ Replicate, transpose 13 | + / TA × TB ⍝ Compute final array 14 | } 15 | 16 | A ← 3 2 ⍴ ⍳ 5 ⍝ Example input A 17 | B ← ⍉ A ⍝ Example input B 18 | 19 | R ← A inner B 20 | 21 | R2 ← ×/ +/ R 22 | 23 | ⍝ 1 3 5 24 | ⍝ 2 4 1 25 | ⍝ 26 | ⍝ 1 2 5 11 7 -+-> 23 | 27 | ⍝ 3 4 11 25 19 -+-> 55 × 28 | ⍝ 5 1 7 19 26 -+-> 52 | 29 | ⍝ 65780 v 30 | -------------------------------------------------------------------------------- /doc/primes.fut: -------------------------------------------------------------------------------- 1 | fun real main() = 2 | let t_v1 = drop1_int(1,map(fn int (int x) => (x + 1),iota(9))) in 3 | let t_v7 = rearrange((1,0),reshape((8,8),reshape1_int((8 * (8 * 1)),reshape(((size(0,t_v1) * 1)),t_v1)))) in 4 | let t_v8 = reshape((8,8),reshape1_int((8 * (8 * 1)),reshape(((size(0,t_v1) * 1)),t_v1))) in 5 | let t_v11 = map(fn [int] ([int] x,[int] y) => map(resi,zip(x,y)),zip(t_v7,t_v8)) in 6 | let t_v13 = map(fn [bool] ([int] x) => map(fn bool (int t_v12) => (0 == t_v12),x),t_v11) in 7 | let t_v18 = rearrange((0),map(fn int ([int] x) => reduce(+,0,x),map(fn [int] ([bool] x) => map(boolToInt,x),rearrange((1,0),t_v13)))) in 8 | let t_v20 = map(fn bool (int t_v19) => (1 == t_v19),t_v18) in 9 | let t_v24 = reduce(+,0,map(boolToInt,t_v20)) in 10 | toFloat(t_v24) -------------------------------------------------------------------------------- /tests/basic_tests/innerLegrand5.3.apl: -------------------------------------------------------------------------------- 1 | ⍝ ******************* 2 | ⍝ Example 1 3 | ⍝ ******************* 4 | 5 | HMS ← 3 44 29 6 | good ← +/ 3600 60 1 × HMS ⍝ --> 13469 7 | excelent ← 3600 60 1 +.× HMS ⍝ --> 13469 8 | 9 | ex1 ← good + excelent ⍝ --> 13469+13469 = 26938 10 | 11 | ⍝ ******************* 12 | ⍝ Example 2 13 | ⍝ ******************* 14 | 15 | Price ← 6 4.2 1.5 8.9 31 18 16 | Qty ← 2 6 3 5 1 0.5 17 | 18 | beginnerSolution ← +/ Price × Qty ⍝ --> 126.2 19 | innerSolution ← Price +.× Qty ⍝ --> 126.2 20 | 21 | ex2 ← beginnerSolution + innerSolution ⍝ --> 252.4 22 | 23 | ⍝ ******************* 24 | ⍝ Total 25 | ⍝ ******************* 26 | ex1 + ex2 ⍝ --> 26938 + 252.4 = 27190.4 -------------------------------------------------------------------------------- /tests/benchmarks/eacheaster.apl: -------------------------------------------------------------------------------- 1 | easter←{ ⍝ Easter Sunday in year ⍵ 2 | G←1+19|⍵ ⍝ year "golden number" 3 | C←1+⌊⍵÷100 ⍝ Century: eg 1984 → 20th 4 | X← ¯12 + ⌊ C×3÷4 ⍝ yrs in which leap yr omitted 5 | Z← ¯5 + ⌊ (5+8×C)÷25 ⍝ synch Easter & moon's orbit 6 | S←(⌊(5×⍵)÷4)-X+10 ⍝ find Sunday 7 | E←30|(11×G)+20+Z-X ⍝ Epact 8 | F←E+(E=24)∨(E=25)∧G>11 ⍝ (when full moon occurs) 9 | N←(30×F>23)+44-F ⍝ find full moon 10 | N←N+7-7|S+N ⍝ advance to Sunday 11 | M←3+N>31 ⍝ month: March or April 12 | D←N-31×N>31 ⍝ day within month 13 | 10000 100 1+.×⍵ M D ⍝ yyyymmdd 14 | } 15 | 16 | a ← easter ¨ 2014+⍳ 4 17 | 18 | +/a 19 | -------------------------------------------------------------------------------- /tests/benchmarks/easter3000.apl: -------------------------------------------------------------------------------- 1 | easter←{ ⍝ Easter Sunday in year ⍵ 2 | G←1+19|⍵ ⍝ year "golden number" 3 | C←1+⌊⍵÷100 ⍝ Century: eg 1984 → 20th 4 | X← ¯12 + ⌊ C×3÷4 ⍝ yrs in which leap yr omitted 5 | Z← ¯5 + ⌊ (5+8×C)÷25 ⍝ synch Easter & moon's orbit 6 | S←(⌊(5×⍵)÷4)-X+10 ⍝ find Sunday 7 | E←30|(11×G)+20+Z-X ⍝ Epact 8 | F←E+(E=24)∨(E=25)∧G>11 ⍝ (when full moon occurs) 9 | N←(30×F>23)+44-F ⍝ find full moon 10 | N←N+7-7|S+N ⍝ advance to Sunday 11 | M←3+N>31 ⍝ month: March or April 12 | D←N-31×N>31 ⍝ day within month 13 | 10000 100 1+.×⍵ M D ⍝ yyyymmdd 14 | } 15 | 16 | run ← { 17 | ⌈/easter¨⍳ 3000+⍵ 18 | } 19 | 20 | a←⌊/run ¨ ⍳ 4000 21 | 22 | a 23 | -------------------------------------------------------------------------------- /tests/benchmarks/life.apl: -------------------------------------------------------------------------------- 1 | ⍝ Conway's Game of Life in APL without the use of nested arrays 2 | ⍝ Martin Elsman, 2014-11-10 3 | 4 | ⍝ Function computing the next generation of a board of life 5 | life ← { 6 | rowsum ← { 7 | (¯1⌽⍵) + ⍵ + 1⌽⍵ 8 | } 9 | neighbor ← { 10 | (rowsum ¯1⊖⍵) + (rowsum ⍵) + rowsum 1⊖⍵ 11 | } 12 | n ← neighbor ⍵ 13 | (n=3) ∨ (n=4) ∧ ⍵ 14 | } 15 | 16 | lifepr ← { 17 | ⍝ ⎕ ← life ⍵ 18 | life ⍵ 19 | } 20 | 21 | nlife ← { 22 | (lifepr ⍣ ⍺) ⍵ 23 | } 24 | 25 | glider ← 3 3⍴1 1 1 1 0 0 0 1 0 26 | 27 | board ← ⍉ ¯10 ↑ ⍉ ¯10 ↑ glider 28 | 29 | square ← { x ← (5 ⊖ ⍵), 3 ⌽ ⍉ ⍵ ⋄ x ⍪ 4 ⊖ x } 30 | 31 | board ← square board 32 | board ← square board 33 | 34 | a ← 20000 nlife board 35 | 36 | b ← life a 37 | 38 | ⍝ ⎕ ← a 39 | 40 | ⍝ ⎕ ← 'Stable: ' 41 | s ← ∧/∧/a=b 42 | ⎕ ← s+0 43 | s 44 | -------------------------------------------------------------------------------- /tools/apl2opencl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | APLT=${APLT:-aplt} 4 | FUTHARK=${FUTHARK:-futhark-opencl} 5 | T2F=${T2F:-tail2futhark} 6 | 7 | FUTHARKFLAGS='' 8 | 9 | if [ $# -ne 1 ]; then 10 | echo "Usage: $0 " 11 | exit 1 12 | fi 13 | 14 | if ! [ "$TAIL_ROOT" ]; then 15 | echo '$TAIL_ROOT must point to a checkout of the apltail repository.' 16 | exit 1 17 | fi 18 | 19 | set -e # Die on error. 20 | 21 | TAIL_PRELUDE=${TAIL_ROOT}/lib/prelude.apl 22 | TAIL_INCLUDE=${TAIL_ROOT}/include 23 | 24 | apl_source=$1 25 | tail_source=${apl_source%.*}.tail 26 | fut_source=${apl_source%.*}.fut 27 | dest=${apl_source%.*} 28 | 29 | $APLT -p_types -s_tail -silent -c -o "$tail_source" "$TAIL_PRELUDE" "$apl_source" 30 | $T2F -o "$fut_source" "$tail_source" --float-as-single 31 | $FUTHARK $FUTHARKFLAGS "$fut_source" -o "$dest" 32 | -------------------------------------------------------------------------------- /tests/benchmarks/easter.apl: -------------------------------------------------------------------------------- 1 | easter←{ ⍝ Easter Sunday in year ⍵ 2 | G←1+19|⍵ ⍝ year "golden number" 3 | C←1+⌊⍵÷100 ⍝ Century: eg 1984 → 20th 4 | X← ¯12 + ⌊ C×3÷4 ⍝ yrs in which leap yr omitted 5 | Z← ¯5 + ⌊ (5+8×C)÷25 ⍝ synch Easter & moon's orbit 6 | S←(⌊(5×⍵)÷4)-X+10 ⍝ find Sunday 7 | E←30|(11×G)+20+Z-X ⍝ Epact 8 | F←E+(E=24)∨(E=25)∧G>11 ⍝ (when full moon occurs) 9 | N←(30×F>23)+44-F ⍝ find full moon 10 | N←N+7-7|S+N ⍝ advance to Sunday 11 | M←3+N>31 ⍝ month: March or April 12 | D←N-31×N>31 ⍝ day within month 13 | 10000 100 1+.×⍵ M D ⍝ yyyymmdd 14 | } 15 | 16 | a ← easter 2014 17 | b ← easter 2015 18 | c ← easter 2016 19 | d ← easter 2017 20 | 21 | +/ a b c d 22 | -------------------------------------------------------------------------------- /tools/apl2python: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | APLT=${APLT:-aplt} 4 | FUTHARK=${FUTHARK:-futhark-py} 5 | T2F=${T2F:-tail2futhark} 6 | 7 | FUTHARKFLAGS='--unsafe --real-as-single' 8 | 9 | if [ $# -ne 1 ]; then 10 | echo "Usage: $0 " 11 | exit 1 12 | fi 13 | 14 | if ! [ "$TAIL_ROOT" ]; then 15 | echo '$TAIL_ROOT must point to a checkout of the apltail repository.' 16 | exit 1 17 | fi 18 | 19 | set -e # Die on error. 20 | 21 | TAIL_PRELUDE=${TAIL_ROOT}/lib/prelude.apl 22 | TAIL_INCLUDE=${TAIL_ROOT}/include 23 | 24 | apl_source=$1 25 | tail_source=${apl_source%.*}.tail 26 | fut_source=${apl_source%.*}.fut 27 | py_source=${apl_source%.*}.py 28 | 29 | $APLT -p_types -p_tail -silent -c -o "$tail_source" "$TAIL_PRELUDE" "$apl_source" 30 | $T2F -o "$fut_source" "$tail_source" 31 | $FUTHARK $FUTHARKFLAGS "$fut_source" -o "$py_source" 32 | -------------------------------------------------------------------------------- /tools/apl2pyopencl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | APLT=${APLT:-aplt} 4 | FUTHARK=${FUTHARK:-futhark-pyopencl} 5 | T2F=${T2F:-tail2futhark} 6 | 7 | FUTHARKFLAGS='--library' 8 | 9 | if [ $# -ne 1 ]; then 10 | echo "Usage: $0 " 11 | exit 1 12 | fi 13 | 14 | if ! [ "$TAIL_ROOT" ]; then 15 | echo '$TAIL_ROOT must point to a checkout of the apltail repository.' 16 | exit 1 17 | fi 18 | 19 | set -e # Die on error. 20 | 21 | TAIL_PRELUDE=${TAIL_ROOT}/lib/prelude.apl 22 | TAIL_INCLUDE=${TAIL_ROOT}/include 23 | 24 | apl_source=$1 25 | tail_source=${apl_source%.*}.tail 26 | fut_source=${apl_source%.*}.fut 27 | py_source=${apl_source%.*}.py 28 | 29 | $APLT -p_types -p_tail -silent -c -o "$tail_source" "$TAIL_PRELUDE" "$apl_source" 30 | $T2F -o "$fut_source" "$tail_source" --float-as-single 31 | $FUTHARK $FUTHARKFLAGS "$fut_source" -o "$py_source" 32 | -------------------------------------------------------------------------------- /tests/common.mk: -------------------------------------------------------------------------------- 1 | # Standard paths and definitions used by all the Makefiles in here. 2 | 3 | ifndef TAIL_ROOT 4 | $(error TAIL_ROOT is not set) 5 | endif 6 | 7 | .SECONDARY: 8 | 9 | T2F ?= tail2futhark 10 | FUTHARKC ?= futhark-c 11 | FUTHARKOPENCL ?= futhark-opencl 12 | APLT ?= $(TAIL_ROOT)/aplt 13 | PRELUDE ?= $(TAIL_ROOT)/lib/prelude.apl 14 | INCLUDE ?= $(TAIL_ROOT)/include 15 | 16 | tail_%.c: %.apl 17 | $(APLT) -silent -c -O2 -opt_hoist -oc $@ $(PRELUDE) $< 18 | 19 | tail_%: tail_%.c 20 | gcc -lm -std=c99 -O3 -o $@ -I $(INCLUDE) $< 21 | 22 | %.tail: %.apl 23 | $(APLT) -p_types -p_tail -s_tail -silent -c -o $@ $(PRELUDE) $< 24 | 25 | %.fut: %.tail 26 | $(T2F) -o $@ $< 27 | 28 | %.futu: %.tail 29 | $(T2F) --unsafe -o $@ $< 30 | 31 | fut_%: %.fut 32 | $(FUTHARKC) -o $@ $< 33 | 34 | futopencl_%: %.futu 35 | $(FUTHARKOPENCL) -o $@ $< 36 | -------------------------------------------------------------------------------- /tests/basic_tests/easter.apl: -------------------------------------------------------------------------------- 1 | easter←{ ⍝ Easter Sunday in year ⍵ 2 | G←1+19|⍵ ⍝ year "golden number" 3 | C←1+⌊⍵÷100 ⍝ Century: eg 1984 → 20th 4 | X← ¯12 + ⌊ C×3÷4 ⍝ yrs in which leap yr omitted 5 | Z← ¯5 + ⌊ (5+8×C)÷25 ⍝ synch Easter & moon's orbit 6 | S←(⌊(5×⍵)÷4)-X+10 ⍝ find Sunday 7 | E←30|(11×G)+20+Z-X ⍝ Epact 8 | F←E+(E=24)∨(E=25)∧G>11 ⍝ (when full moon occurs) 9 | N←(30×F>23)+44-F ⍝ find full moon 10 | N←N+7-7|S+N ⍝ advance to Sunday 11 | M←3+N>31 ⍝ month: March or April 12 | D←N-31×N>31 ⍝ day within month 13 | 10000 100 1+.×⍵ M D ⍝ yyyymmdd 14 | } 15 | 16 | T1 ← 20140420=easter 2014 17 | T2 ← 20150405=easter 2015 18 | T3 ← 20160327=easter 2016 19 | T4 ← 20170416=easter 2017 20 | 21 | ∧/T1 T2 T3 T4 22 | -------------------------------------------------------------------------------- /tests/basic_tests/dtransp.apl: -------------------------------------------------------------------------------- 1 | A ← 2 3 4 ⍴ ⍳ 24 2 | 3 | B ← 2 1 3 ⍉ A ⍝ ⍴B = 3 2 4 4 | 5 | T1 ← ∧/(⍴B)=3 2 4 6 | 7 | T2 ← ∧/∧/(+/B)=3 2 ⍴ 10 58 26 74 42 90 8 | ⍝ --> 10 58 9 | ⍝ 26 74 10 | ⍝ 42 90 11 | 12 | ⍝ The following example requires a correct definition of exchange - see ARRAY'14 13 | ⍝ The paper is wrong wrt the specification of exchange - here is a correct 14 | ⍝ specification: 15 | ⍝ exchange_p(q) = r where r(p(i)) = q(i) 16 | 17 | C ← 3 1 2 ⍉ A ⍝ ⍴C = 3 4 2 18 | 19 | T3 ← ∧/(⍴C)=3 4 2 20 | 21 | 22 | T4 ← ∧/∧/(+/C)=3 4 ⍴ 14 16 18 20 22 24 26 28 30 32 34 36 23 | ⍝ --> 14 16 18 20 24 | ⍝ 22 24 26 28 25 | ⍝ 30 32 34 36 26 | 27 | ∧/T1 T2 T3 T4 28 | 29 | -------------------------------------------------------------------------------- /tests/benchmarks/lifein.apl: -------------------------------------------------------------------------------- 1 | ⍝ Conway's Game of Life in APL without the use of nested arrays 2 | ⍝ Martin Elsman, 2014-11-10 3 | 4 | ⍝ Function computing the next generation of a board of life 5 | life ← { 6 | rowsum ← { 7 | (¯1⌽⍵) + ⍵ + 1⌽⍵ 8 | } 9 | neighbor ← { 10 | (rowsum ¯1⊖⍵) + (rowsum ⍵) + rowsum 1⊖⍵ 11 | } 12 | n ← neighbor ⍵ 13 | (n=3) ∨ (n=4) ∧ ⍵ 14 | } 15 | 16 | lifepr ← { 17 | ⍝ ⎕ ← life ⍵ 18 | life ⍵ 19 | } 20 | 21 | nlife ← { 22 | (lifepr ⍣ ⍺) ⍵ 23 | } 24 | 25 | ⍝ input as generated by ./rle --flat < file.in > file.out 26 | 27 | dim ← ReadCSVInt 'dim.txt' 28 | dim ← 2 ↑ dim 29 | data ← ReadCSVInt 'data.txt' 30 | data ← data > 0 31 | 32 | board ← dim ⍴ data 33 | 34 | a ← 201 nlife board 35 | 36 | b ← life a 37 | 38 | layout ← { 39 | arr ← ' o*' 40 | arr[⍵+1] 41 | } 42 | 43 | ⎕ ← layout¨a 44 | 45 | ⍝ ⎕ ← 'Stable: ' 46 | ⍝ s ← ∧/∧/a=b 47 | ⍝ ⎕ ← s+0 48 | 1 49 | -------------------------------------------------------------------------------- /tests/basic_tests/idx.apl: -------------------------------------------------------------------------------- 1 | 2 | V ← ⍳ 28 3 | A ← 5 7 ⍴ ⍳ 35 4 | A3 ← 5 4 3 ⍴ ⍳ 60 5 | X ← ⍳ 2 6 | Y ← 1 4 2 7 | 8 | V1 ← V[5] 9 | T1 ← V1=5 ⍝ → [](5) 10 | 11 | V2 ← V[5 2] 12 | T2 ← ∧/V2=5 2 ⍝ → [2](5,2) 13 | 14 | B1 ← A[1;] 15 | T3 ← ∧/B1=⍳7 ⍝ → [7](1,2,3,4,5,6,7) 16 | 17 | B2 ← A[2;] 18 | T4 ← ∧/B2=7+⍳7 ⍝ → [7](8,9,10,11,12,13,14) 19 | 20 | B2_ ← A[;2] 21 | T5 ← ∧/B2_=2 9 16 23 30 ⍝ → [5](2,9,16,23,30) 22 | 23 | ⍝ C ← A[1 1;] 24 | ⍝ ⎕ ← C ⍝ → 1 2 3 4 5 6 7 25 | ⍝ 1 2 3 4 5 6 7 26 | T6 ← 1 27 | 28 | Z ← A[2; 3 2 3] 29 | T7 ← ∧/Z=10 9 10 ⍝ → [3](10,9,10) 30 | 31 | ⍝ D ← A[1 0;3 2] 32 | ⍝ E ← A[;X] 33 | ⍝ F ← A[Y;X] 34 | ⍝ G ← A[Y;] 35 | ⍝ H ← A3[;;2 2] 36 | ⍝ I ← A3[;2 2;] 37 | ⍝ J ← A3[X;;] 38 | 39 | J1_2 ← A3[2;;] 40 | T8 ← ∧/∧/J1_2=4 3 ⍴ 12+⍳12 41 | 42 | J2_2 ← 1 ↓ A3[;2;] 43 | T9 ← ∧/∧/J2_2=4 3 ⍴ 16 17 18 28 29 30 40 41 42 52 53 54 44 | 45 | J3_2 ← 1 ↓ A3[;;2] 46 | T10 ← ∧/∧/J3_2=4 4 ⍴ 11+3×⍳16 47 | 48 | ∧/ T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 -------------------------------------------------------------------------------- /.travis-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # From https://github.com/commercialhaskell/stack/blob/master/.travis.yml 4 | 5 | set -eux 6 | 7 | travis_retry() { 8 | cmd=$* 9 | $cmd || (sleep 2 && $cmd) || (sleep 10 && $cmd) 10 | } 11 | 12 | fetch_stack_osx() { 13 | curl -skL https://www.stackage.org/stack/osx-x86_64 | tar xz --strip-components=1 --include '*/stack' -C ~/.local/bin; 14 | } 15 | 16 | fetch_stack_linux() { 17 | curl -sL https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'; 18 | } 19 | 20 | case "$BUILD" in 21 | stack) 22 | mkdir -p ~/.local/bin; 23 | if [ `uname` = "Darwin" ]; then 24 | travis_retry fetch_stack_osx 25 | else 26 | travis_retry fetch_stack_linux 27 | fi; 28 | 29 | travis_retry stack --no-terminal setup; 30 | ;; 31 | cabal) 32 | mkdir -p $HOME/.cabal 33 | cat > $HOME/.cabal/config < 1 5 9 7 | ⍝ 2 6 10 8 | ⍝ 3 7 11 9 | ⍝ 4 8 12 10 | V1 ← 1 ⌽ V 11 | T1 ← ∧/V1=2 3 4 5 1 12 | 13 | V2 ← ¯1 ⌽ V 14 | T2 ← ∧/V2=5 1 2 3 4 15 | 16 | A3 ← 1 ⌽ A 17 | T3 ← ∧/∧/A3=3 4 ⍴ 2 3 4 1 6 7 8 5 10 11 12 9 18 | T4 ← ∧/(+/A3)=10 26 42 19 | 20 | rot ← { (⍉ ⍺ ↓ ⍉ ⍵) , ⍉ ⍺ ↑ ⍉ ⍵ } 21 | X5 ← 1 rot A ⍝ --> 2 3 4 1 22 | ⍝ 6 7 8 5 23 | ⍝ 10 11 12 9 24 | V5 ← +/ X5 ⍝ --> [3](10,26,42) 25 | T5 ← ∧/V5=10 26 42 26 | 27 | M6 ← 2 ↑ TA ⍝ --> 1 5 9 28 | ⍝ 2 6 10 29 | T6 ← ∧/∧/M6=2 3 ⍴ 1 5 9 2 6 10 30 | 31 | M7 ← ⍉ M6 ⍝ --> 1 2 32 | ⍝ 5 6 33 | ⍝ 9 10 34 | T7 ← ∧/∧/M7=3 2 ⍴ 1 2 5 6 9 10 35 | 36 | + / T1 T2 T3 T4 T5 T6 T7 -------------------------------------------------------------------------------- /tests/basic_tests/primes0.apl: -------------------------------------------------------------------------------- 1 | A←1↓⍳9 ⍝ 2 3 4 5 6 7 8 9 2 | 3 | residual ← A∘.|A ⍝ 0 1 0 1 0 1 0 1 4 | ⍝ 2 0 1 2 0 1 2 0 5 | ⍝ 2 3 0 1 2 3 0 1 6 | ⍝ 2 3 4 0 1 2 3 4 7 | ⍝ 2 3 4 5 0 1 2 3 8 | ⍝ 2 3 4 5 6 0 1 2 9 | ⍝ 2 3 4 5 6 7 0 1 10 | ⍝ 2 3 4 5 6 7 8 0 11 | 12 | b ← 0=residual ⍝ 1 0 1 0 1 0 1 0 13 | ⍝ 0 1 0 0 1 0 0 1 14 | ⍝ 0 0 1 0 0 0 1 0 15 | ⍝ 0 0 0 1 0 0 0 0 16 | ⍝ 0 0 0 0 1 0 0 0 17 | ⍝ 0 0 0 0 0 1 0 0 18 | ⍝ 0 0 0 0 0 0 1 0 19 | ⍝ 0 0 0 0 0 0 0 1 20 | 21 | c ← +⌿ b ⍝ 1 1 2 1 3 1 3 2 22 | 23 | d ← 1=c ⍝ 1 1 0 1 0 1 0 0 24 | 25 | e ← +/ d ⍝ 4 <--- number of prime numbers less than 10 26 | 27 | ⍝ (1=+⌿0=residual)/A ⍝ compress not supported yet 28 | -------------------------------------------------------------------------------- /tests/benchmarks/primes0.apl: -------------------------------------------------------------------------------- 1 | A←1↓⍳9999 ⍝ 2 3 4 5 6 7 8 9 2 | 3 | residual ← A∘.|A ⍝ 0 1 0 1 0 1 0 1 4 | ⍝ 2 0 1 2 0 1 2 0 5 | ⍝ 2 3 0 1 2 3 0 1 6 | ⍝ 2 3 4 0 1 2 3 4 7 | ⍝ 2 3 4 5 0 1 2 3 8 | ⍝ 2 3 4 5 6 0 1 2 9 | ⍝ 2 3 4 5 6 7 0 1 10 | ⍝ 2 3 4 5 6 7 8 0 11 | 12 | b ← 0=residual ⍝ 1 0 1 0 1 0 1 0 13 | ⍝ 0 1 0 0 1 0 0 1 14 | ⍝ 0 0 1 0 0 0 1 0 15 | ⍝ 0 0 0 1 0 0 0 0 16 | ⍝ 0 0 0 0 1 0 0 0 17 | ⍝ 0 0 0 0 0 1 0 0 18 | ⍝ 0 0 0 0 0 0 1 0 19 | ⍝ 0 0 0 0 0 0 0 1 20 | 21 | c ← +⌿ b ⍝ 1 1 2 1 3 1 3 2 22 | 23 | d ← 1=c ⍝ 1 1 0 1 0 1 0 0 24 | 25 | e ← +/ d ⍝ 4 <--- number of prime numbers less than 10 26 | 27 | ⍝ (1=+⌿0=residual)/A ⍝ compress not supported yet 28 | -------------------------------------------------------------------------------- /doc/ku-template.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | \usepackage[a4paper, hmargin={2.8cm, 2.8cm}, vmargin={2.5cm, 2.5cm}]{geometry} 3 | \usepackage{eso-pic} % \AddToShipoutPicture 4 | \usepackage{graphicx} % \includegraphics 5 | 6 | %% Change `ku-farve` to `nat-farve` to use SCIENCE's old colors or 7 | %% `natbio-farve` to use SCIENCE's new colors and logo. 8 | \def \ColourPDF {include/ku-farve} 9 | 10 | %% Change `ku-en` to `nat-en` to use the `Faculty of Science` header 11 | \def \TitlePDF {include/ku-en} % University of Copenhagen 12 | 13 | \title{ 14 | \vspace{3cm} 15 | \Huge{Some Title} \\ 16 | \Large{More elaborate subtitle} 17 | } 18 | 19 | \author{ 20 | \Large{Philip Munksgaard} 21 | \\ \texttt{pmunksgaard@gmail.com} \\ 22 | } 23 | 24 | \date{ 25 | \today 26 | } 27 | 28 | \begin{document} 29 | 30 | 31 | \AddToShipoutPicture*{\put(0,0){\includegraphics*[viewport=0 0 700 600]{\ColourPDF}}} 32 | \AddToShipoutPicture*{\put(0,602){\includegraphics*[viewport=0 600 700 1600]{\ColourPDF}}} 33 | 34 | \AddToShipoutPicture*{\put(0,0){\includegraphics*{\TitlePDF}}} 35 | 36 | \clearpage\maketitle 37 | \thispagestyle{empty} 38 | 39 | \newpage 40 | 41 | %% Write your dissertation here. 42 | 43 | \end{document} 44 | -------------------------------------------------------------------------------- /stack.yaml: -------------------------------------------------------------------------------- 1 | # This file was automatically generated by stack init 2 | # For more information, see: http://docs.haskellstack.org/en/stable/yaml_configuration/ 3 | 4 | # Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2) 5 | resolver: lts-9.2 6 | 7 | # Local packages, usually specified by relative directory name 8 | packages: 9 | - '.' 10 | # Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3) 11 | extra-deps: [] 12 | 13 | # Override default flag values for local packages and extra-deps 14 | flags: {} 15 | 16 | # Extra package databases containing global packages 17 | extra-package-dbs: [] 18 | 19 | # Control whether we use the GHC we find on the path 20 | # system-ghc: true 21 | 22 | # Require a specific version of stack, using version ranges 23 | # require-stack-version: -any # Default 24 | # require-stack-version: >= 1.0.0 25 | 26 | # Override the architecture used by stack, especially useful on Windows 27 | # arch: i386 28 | # arch: x86_64 29 | 30 | # Extra directories used by stack for building 31 | # extra-include-dirs: [/path/to/dir] 32 | # extra-lib-dirs: [/path/to/dir] 33 | 34 | # Allow a newer minor version of GHC than the snapshot specifies 35 | # compiler-check: newer-minor 36 | -------------------------------------------------------------------------------- /tests/Test.hs: -------------------------------------------------------------------------------- 1 | module Main(main) where 2 | 3 | import Control.Monad 4 | import System.Process 5 | import System.FilePath 6 | import System.Exit 7 | 8 | import Test.Tasty 9 | import Test.Tasty.Providers 10 | import Test.Tasty.Golden 11 | import Test.Tasty.Golden.Manage as G 12 | 13 | main :: IO () 14 | main = do 15 | files <- findByExtension [".tail"] "tests/basic_tests" 16 | let tests = testGroup "Tests"$ map (\f -> goldenVsFile f (replaceExtension f "ok") (replaceExtension f "out") (makeTest f)) files 17 | G.defaultMain tests 18 | 19 | makeTest :: FilePath -> IO () 20 | makeTest file = do 21 | ret <- system ("make -s -B -C " ++ dir ++ " " ++ outname ++ "> /dev/null") 22 | unless (ret == ExitSuccess) $ fail "Test failed." 23 | where (dir,name) = splitFileName file 24 | outname = name `replaceExtension` "out" 25 | 26 | 27 | --tests = testGroup "Tests" [crashTests,outputTests] 28 | -- 29 | --crashTests = testGroup "Crash Tests" [testProgram "test2.tail" "tail2futhark" ["tests/test2.tail"] Nothing] 30 | -- 31 | --outputTests = testGroup "Output Tests" [goldenVsFile "integer test" "tests/integer.fut" "tests/integer_out.fut" integerTest] 32 | -- 33 | --integerTest :: IO () 34 | --integerTest = rawSystem "tail2futhark" ["tests/integer.tail", "-o", "tests/integer_out.fut"] >> return () 35 | -------------------------------------------------------------------------------- /tests/basic_tests/rot.apl: -------------------------------------------------------------------------------- 1 | ⍝ Rotate along the last axis as in (1 ⌽ A) 2 | 3 | rot ← { (⍉ ⍺ ↓ ⍉ ⍵) , ⍉ ⍺ ↑ ⍉ ⍵ } 4 | 5 | A ← 3 4 ⍴ ⍳ 12 6 | 7 | X ← 1 rot A ⍝ --> 2 3 4 1 8 | ⍝ 6 7 8 5 9 | ⍝ 10 11 12 9 10 | 11 | V1 ← +/ X ⍝ --> [3](10,26,42) 12 | 13 | V2 ← +/ 1 ⌽ A ⍝ --> [3](10,26,42) 14 | 15 | Ares ← ∧/V1=V2 16 | 17 | B ← 3 4 ⍴ ⍳ 9 18 | 19 | B1 ← 1 ⌽ B ⍝ --> 2 3 4 1 20 | ⍝ 6 7 8 5 21 | ⍝ 1 2 3 9 22 | 23 | B2 ← 4 ⌽ B ⍝ --> 1 2 3 4 24 | ⍝ 5 6 7 8 25 | ⍝ 9 1 2 3 26 | 27 | B3 ← ¯1 ⌽ B ⍝ --> 4 1 2 3 28 | ⍝ 8 5 6 7 29 | ⍝ 3 9 1 2 30 | 31 | B4 ← ¯4 ⌽ B ⍝ --> 1 2 3 4 32 | ⍝ 5 6 7 8 33 | ⍝ 9 1 2 3 34 | 35 | B5 ← 0 ⌽ B ⍝ --> 1 2 3 4 36 | ⍝ 5 6 7 8 37 | ⍝ 9 1 2 3 38 | 39 | B1ok ← 3 4 ⍴ 2 3 4 1 6 7 8 5 1 2 3 9 40 | B2ok ← 3 4 ⍴ 1 2 3 4 5 6 7 8 9 1 2 3 41 | B3ok ← 3 4 ⍴ 4 1 2 3 8 5 6 7 3 9 1 2 42 | 43 | Bres ← (∧/∧/B2=B4) ∧ (∧/∧/B4=B5) ∧ (∧/∧/B1=B1ok) ∧ (∧/∧/B2=B2ok) ∧ (∧/∧/B3=B3ok) 44 | 45 | ∧ / Ares Bres -------------------------------------------------------------------------------- /src/Tail2Futhark/TAIL/AST.hs: -------------------------------------------------------------------------------- 1 | -- | Originally from APLAcc by Michael Budde 2 | module Tail2Futhark.TAIL.AST where 3 | 4 | type Ident = String 5 | 6 | data Rank 7 | = R Integer 8 | -- | Rv String Unsupported 9 | -- | Radd Rank Rank Unsupported 10 | deriving (Show) 11 | 12 | data BType = IntT 13 | | DoubleT 14 | | BoolT 15 | | CharT 16 | | ComplexT 17 | | Btyv Ident 18 | deriving (Show, Eq) 19 | 20 | data Type 21 | = ArrT BType Rank 22 | | VecT BType Rank 23 | | S BType Rank 24 | | SV BType Rank 25 | | TupT [Type] 26 | -- | FunT Type Type 27 | -- | ShT Rank 28 | -- | SiT Rank 29 | -- | ViT Rank 30 | deriving (Show) 31 | 32 | scalar :: BType -> Type 33 | scalar b = ArrT b (R 0) 34 | 35 | int, double :: Type 36 | int = scalar IntT 37 | double = scalar DoubleT 38 | 39 | 40 | data Shape = Sh [Integer] 41 | deriving (Show) 42 | 43 | type InstDecl = ([BType], [Integer]) 44 | 45 | data Exp 46 | = Var Ident 47 | | I Integer 48 | | D Double 49 | | C Char 50 | | B Bool 51 | | X Double Double 52 | | Inf 53 | | Neg Exp 54 | | Let Ident Type Exp Exp 55 | | Prj (Maybe Integer) Integer Exp 56 | | Op Ident (Maybe InstDecl) [Exp] 57 | | Fn Ident Type Exp 58 | | Vc [Exp] 59 | | Ts [Exp] 60 | deriving (Show) 61 | 62 | type Program = Exp 63 | -------------------------------------------------------------------------------- /ops: -------------------------------------------------------------------------------- 1 | Funktioner Testet* Kommentarer 2 | addi testet 3 | addd ikke testet 4 | iotaV ikke testet 5 | iota ikke testet ens med iotaV 6 | eachV testet 7 | each testst 8 | reduce(V) testet 9 | reduce ikke testet 10 | shapeV ikke testet ens med shape 11 | shape ikke testet 12 | reshape ----------------- eksisterer ikke!! Er erstattet med reshape0 13 | reshape0 delvis testet is the normal reshape, NB virker ikke på tom liste 14 | reverse ----------------- erstattet med vreverse 15 | vreverse note: testet i vrev i Martins tests 16 | rotateV 17 | vrotateV 18 | rotate ----------------- erstattet med reshape og rotateV 19 | transp ikke testet 20 | transp2 21 | takeV delvis testet 22 | take delvis testet 23 | dropV 24 | drop 25 | consV 26 | cons 27 | snocV 28 | snoc 29 | firstV ikke testet NB!! test failed - not correct - futhark parse error 30 | first 31 | zipWith testet 32 | catV testet 33 | cat ikke testet 34 | 35 | addi, addd, iotaV, iota, eachV, each, reduce(V), reduce, shapeV, shape, reshape, reshape0, reverse, vreverse, rotateV, vrotateV, rotate, transp, transp2, takeV, take, dropV, drop, consV, cons, snocV, snoc, firstV, first, zipWith, catV, cat 36 | -------------------------------------------------------------------------------- /src/Options.hs: -------------------------------------------------------------------------------- 1 | module Options where 2 | 3 | import System.Console.GetOpt 4 | 5 | -- Option record -- 6 | data Options = Options { outputFile :: Maybe String 7 | , includeLibs :: Bool 8 | , floatAsSingle :: Bool 9 | , unsafe :: Bool 10 | , library :: Bool 11 | } 12 | deriving Show 13 | 14 | defaultOptions :: Options 15 | defaultOptions = Options {outputFile = Nothing, 16 | includeLibs = True, 17 | floatAsSingle = False, 18 | unsafe = False, 19 | library = False 20 | } 21 | 22 | -- option description -- 23 | options :: [OptDescr (Options -> Options)] 24 | options = [Option ['o'] [] (ReqArg (\arg opt -> opt { outputFile = Just arg }) "FILE") "output FILE", 25 | Option [] ["no-include-lib-funs"] (NoArg $ \opt -> opt {includeLibs = False }) "include lib functions", 26 | Option [] ["float-as-single"] (NoArg $ \opt -> opt { floatAsSingle = True }) 27 | "Compile floating-point numbers as single precision.", 28 | Option [] ["unsafe"] (NoArg $ \opt -> opt { unsafe = True }) 29 | "Disable bounds checking in generated code.", 30 | Option [] ["library"] (NoArg $ \opt -> opt { library = True}) 31 | "Compile as library" 32 | ] 33 | -------------------------------------------------------------------------------- /tests/basic_tests/vrot.apl: -------------------------------------------------------------------------------- 1 | ⍝ Rotate along first axis as in (1 ⊖ A) 2 | 3 | ⍝ scalars 4 | S1 ← 1 ⊖ 13 ⍝ --> 13 5 | S2 ← 34 ⊖ 13 ⍝ --> 13 6 | S3 ← ¯2 ⊖ 13 ⍝ --> 13 7 | 8 | Sres ← 39=S1+S2+S3 9 | 10 | ⍝ vectors 11 | 12 | V1 ← 1 ⊖ 1 2 3 ⍝ --> 2 3 1 13 | V2 ← 4 ⊖ 1 2 3 ⍝ --> 2 3 1 14 | V3 ← ¯1 ⊖ 1 2 3 ⍝ --> 3 1 2 15 | V4 ← 0 ⊖ 1 2 3 ⍝ --> 1 2 3 16 | 17 | Vres ← (8×9×7) = ×/V1+V2+V3+V4 18 | 19 | ⍝ multi-dimensional arrays 20 | A ← 3 4 ⍴ ⍳ 9 21 | 22 | A1 ← 1 ⊖ A ⍝ --> 5 6 7 8 23 | ⍝ 9 1 2 3 24 | ⍝ 1 2 3 4 25 | 26 | A2 ← 4 ⊖ A ⍝ --> 5 6 7 8 27 | ⍝ 9 1 2 3 28 | ⍝ 1 2 3 4 29 | 30 | A3 ← ¯1 ⊖ A ⍝ --> 9 1 2 3 31 | ⍝ 1 2 3 4 32 | ⍝ 5 6 7 8 33 | 34 | A4 ← ¯4 ⊖ A ⍝ --> 9 1 2 3 35 | ⍝ 1 2 3 4 36 | ⍝ 5 6 7 8 37 | 38 | A5 ← 0 ⊖ A ⍝ --> 1 2 3 4 39 | ⍝ 5 6 7 8 40 | ⍝ 9 1 2 3 41 | 42 | Ares ← (∧/∧/A1=A2) ∧ (∧/∧/A3=A4) ∧ (∧/∧/A5=A) ∧ (∧/∧/A3=3 4 ⍴ 9 1 2 3 1 2 3 4 5 6 7 8) 43 | 44 | ⍝ rotating empty vectors 45 | 46 | ⍝ ⎕ ← ¯2 ⊖ ⍬ ⍝ --> [0]() 47 | ⍝ ⎕ ← 11 ⊖ ⍬ ⍝ --> [0]() 48 | ⍝ ⎕ ← 0 ⊖ ⍬ ⍝ --> [0]() 49 | 50 | ⍝ ⎕ ← 12 ⊖ 0 ↑ A ⍝ --> [0,4]() 51 | 52 | Sres + Vres + Ares -------------------------------------------------------------------------------- /tests/benchmarks/mandelbrot.apl: -------------------------------------------------------------------------------- 1 | ⍝ grid-size in left argument (e.g., (1024 768)) 2 | ⍝ X-range, Y-range in right argument 3 | 4 | mandelbrot ← { 5 | X ← ⊃⍺ ⍝ e.g., 1024 6 | Y ← ⊃1↓⍺ ⍝ e.g., 768 7 | xRng ← 2↑⍵ 8 | yRng ← 2↓⍵ 9 | dx ← ((xRng[2])-xRng[1]) ÷ X 10 | dy ← ((yRng[2])-yRng[1]) ÷ Y 11 | cx ← 1 Y X ⍴ (xRng[1]) + dx × ⍳X ⍝ real plane 12 | cy ← ⍉ X Y 1 ⍴ (yRng[1]) + dy × ⍳Y ⍝ img plane 13 | mandel1 ← { ⍝ perform one iteration of mandelbrot - vectorized 14 | arg ← 3 Y X ⍴ ⍵ ⍝ 2 planes for iteratively computed z's and 1 plane for the counter 15 | zx ← 1↑arg ⍝ real plane 16 | zy ← 1↑1↓arg ⍝ imaginary plane 17 | count ← 1↑2↓arg ⍝ count plane 18 | zzx ← cx + (zx × zx) - zy × zy 19 | zzy ← cy + (zx × zy) + zx × zy 20 | conv ← 4 > (zzx × zzx) + zzy × zzy 21 | count2 ← count + 1 - conv 22 | zzx ⍪ zzy ⍪ count2 23 | } 24 | planes ← 3 Y X ⍴ 0 25 | N ← 90 ⍝ iterations 26 | res ← (mandel1 ⍣ N) planes 27 | (2↓res) ÷ N ⍝ return normalized count plane 28 | } 29 | 30 | layout ← { 31 | arr ← '$#Oo*=+:- ' 32 | arr[⍵+1] 33 | } 34 | 35 | norm ← { layout¨ ⌈9 × ⍵ } 36 | 37 | mandelWrap ← { 38 | ⎕ ← norm (⌽⍵) ⍴ ⍵ mandelbrot ¯2 0.75 ¯0.75 0.75 39 | } 40 | 41 | mandelWrap 20 12 42 | 43 | 0 -------------------------------------------------------------------------------- /tests/benchmarks/life/README.md: -------------------------------------------------------------------------------- 1 | ## Game of Life 2 | 3 | Game of Life boards are available in the `.rle` file. The tool `rle` 4 | compiles `.rle` files into boolean vector data suitable for Futhark to eat: 5 | 6 | bash-3.2$ ./rle --flat < ex.rle 7 | [15,15] 8 | [0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0] 9 | Done! 10 | 11 | To get more boards, please consult the [wikilife page](http://www.conwaylife.com/wiki/Category:Patterns). 12 | 13 | First generate the futhark program: 14 | 15 | bash-3.2$ (cd ..; make fut_lifein) 16 | 17 | Then, try to run the executable `fut_lifein` with some input: 18 | 19 | bash-3.2$ make ex.futout 20 | ../fut_lifein < ex.futin ex.futout 21 | Assertion assert_arg_9673 at lifein.fut:196:97-196:97 failed. 22 | /bin/sh: line 1: 79233 Abort trap: 6 ../fut_lifein ex.futout < ex.futin 23 | make: *** [ex.futout] Error 134 24 | bash-3.2$ 25 | 26 | The output may be compared with the result of running the program using the `aplt` interpreter: 27 | 28 | bash-3.2$ make withaplt 29 | ~/gits/apltail/aplt ~/gits/apltail/lib/prelude.apl ../lifein.apl 30 | [Reading file: /Users/mael/gits/apltail/lib/prelude.apl] 31 | [Reading file: ../lifein.apl] 32 | Evaluating 33 | 34 | 35 | ooo ooo 36 | 37 | 38 | 39 | 40 | 41 | ooo ooo 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Result is [](1.0) 51 | -------------------------------------------------------------------------------- /tests/basic_tests/drop.apl: -------------------------------------------------------------------------------- 1 | ⍝ --------------------------------------------- 2 | ⍝ Drop operations on arrays of different ranks 3 | ⍝ --------------------------------------------- 4 | 5 | ⍝ Normal drop 6 | V1 ← 3 ↓ 1 2 3 4 5 ⍝ --> 4 5 7 | T1 ← ∧/V1=4 5 8 | 9 | ⍝ Normal overdrop 10 | V2 ← 6 ↓ 1 2 3 4 ⍝ --> [0]() 11 | T2 ← (1=⊃⍴⍴V2) ∧ 0=≢V2 12 | 13 | ⍝ Multi-dimensional drop 14 | M3 ← 2 ↓ 4 5 ⍴ ⍳ 20 ⍝ --> 11 12 13 14 15 15 | ⍝ 16 17 18 19 20 16 | T3 ← ∧/∧/M3=10+2 5 ⍴ ⍳ 10 17 | 18 | ⍝ Multi-dimensional overdrop 19 | M4 ← 4 ↓ 2 5 ⍴ ⍳ 8 ⍝ --> [0,5]() 20 | T4 ← (0=≢M4) ∧ ∧/0 5=⍴M4 21 | 22 | ⍝ Test of negative drop 23 | V5 ← ¯2 ↓ 1 2 3 4 5 ⍝ --> 1 2 3 24 | T5 ← ∧/V5=1 2 3 25 | 26 | M6 ← ¯2 ↓ 4 2 ⍴ ⍳ 8 ⍝ --> 1 2 27 | ⍝ 3 4 28 | T6 ← ∧/∧/M6=2 2⍴⍳4 29 | 30 | ⍝ Test of underdrop 31 | V7 ← ¯6 ↓ 1 2 3 4 ⍝ --> [0]() 32 | T7 ← (0=≢V7) ∧ 1=⊃⍴⍴V7 33 | 34 | M8 ← ¯6 ↓ 4 2 ⍴ ⍳ 8 ⍝ --> [0,2]() 35 | T8 ← (0=≢M8) ∧ ∧/0 2=⍴M8 36 | 37 | M9 ← ¯4 ↓ 4 2 ⍴ ⍳ 8 ⍝ --> [0,2]() 38 | T9 ← (0=≢M9) ∧ ∧/0 2=⍴M9 39 | 40 | ⍝ Drop from zilde 41 | V10 ← 3 ↓ ⍬ ⍝ --> [0]() 42 | T10 ← (0=≢V10) ∧ 1=⊃⍴⍴V10 43 | 44 | V11 ← ¯3 ↓ ⍬ ⍝ --> [0]() 45 | T11 ← (0=≢V11) ∧ 1=⊃⍴⍴V11 46 | 47 | ⍝ zero-drops 48 | V12 ← 0 ↓ 1 2 3 4 ⍝ --> [4](1,2,3,4) 49 | T12 ← ∧/V12=⍳4 50 | 51 | M13 ← 0 ↓ 2 2 ⍴ ⍳ 4 ⍝ --> 1 2 52 | ⍝ 3 4 53 | T13 ← ∧/∧/M13=2 2⍴⍳4 54 | 55 | V14 ← 0 ↓ ⍬ ⍝ --> [0]() 56 | T14 ← (0=≢V14) ∧ 1=⊃⍴⍴V14 57 | 58 | 59 | ⍝ MEMO: drop from scalars!? 60 | 61 | +/ T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 -------------------------------------------------------------------------------- /src/Main.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Control.Monad 4 | import System.IO 5 | import System.Exit 6 | import System.Console.GetOpt 7 | import System.Environment 8 | import System.FilePath 9 | import Tail2Futhark.TAIL.Parser (parseFile) 10 | import Tail2Futhark.TAIL.AST (Program) 11 | import Tail2Futhark.Futhark.Pretty (pretty) 12 | import Tail2Futhark.Compile (compile) 13 | import Tail2Futhark.Prelude 14 | import Options 15 | 16 | main :: IO () 17 | main = do 18 | cmdargs <- getArgs 19 | let (opts,args,errors) = runArgs cmdargs 20 | checkErrors errors 21 | program <- run (library opts) args 22 | let comp = (\f -> futharkPrelude ++ pretty f) . compile opts 23 | case outputFile opts of 24 | Nothing -> putStrLn . comp $ program 25 | Just f -> withFile f WriteMode (\h -> hPutStr h $ comp $ program) 26 | 27 | 28 | checkErrors :: [String] -> IO () 29 | checkErrors [] = return () 30 | checkErrors errors = hPutStrLn stderr (concat errors ++ usageInfo "Usage: tail2futhark [options] FILE" options) >> exitFailure 31 | 32 | -- nonargs list of functions typed : Options -> Options 33 | runArgs :: [String] -> (Options,[String],[String]) 34 | runArgs cmdargs = (opts,args,errors) 35 | where 36 | (nonargs,args,errors) = getOpt Permute options cmdargs 37 | opts = foldl (.) id nonargs defaultOptions -- MAGIC!!!! - our ooption record 38 | 39 | run :: Bool -> [String] -> IO [(String,Program)] 40 | run True fs = forM fs $ \f -> do 41 | prog <- withFile f ReadMode (flip parseFile f) 42 | return (dropExtension $ takeFileName f, prog) 43 | run False [f] = do 44 | prog <- withFile f ReadMode $ flip parseFile f 45 | return [("main", prog)] 46 | run False _ = do hPutStrLn stderr (usageInfo "Usage: tail2futhark [options] FILE" options) 47 | exitFailure 48 | -------------------------------------------------------------------------------- /tail2futhark.cabal: -------------------------------------------------------------------------------- 1 | 2 | name: tail2futhark 3 | version: 0.1.0.0 4 | synopsis: APL to Futhark 5 | -- description: 6 | -- license: 7 | --license-file: LICENSE 8 | author: Henrik Urms, Anna Sofie Kiehn 9 | maintainer: urmshenrik@gmail.com, a.kiehn89@gmail.com 10 | -- copyright: 11 | category: Language 12 | build-type: Simple 13 | extra-source-files: README.md 14 | cabal-version: >=1.10 15 | 16 | executable tail2futhark 17 | main-is: Main.hs 18 | -- other-modules: 19 | -- other-extensions: 20 | hs-source-dirs: src 21 | build-depends: base >= 4 && < 5, 22 | parsec, 23 | mtl, 24 | containers, 25 | mainland-pretty >= 0.4, 26 | file-embed >= 0.0.9, 27 | filepath 28 | -- hs-source-dirs: 29 | default-language: Haskell2010 30 | 31 | other-modules: Options 32 | Tail2Futhark.Compile 33 | Tail2Futhark.Futhark.AST 34 | Tail2Futhark.Futhark.Pretty 35 | Tail2Futhark.Prelude 36 | Tail2Futhark.TAIL.AST 37 | Tail2Futhark.TAIL.Parser 38 | 39 | 40 | Ghc-Options: -Wall 41 | 42 | -- Ghc-Options: -Wall 43 | 44 | test-suite test 45 | default-language: 46 | Haskell2010 47 | type: 48 | exitcode-stdio-1.0 49 | hs-source-dirs: 50 | tests,src 51 | main-is: 52 | Test.hs 53 | build-depends: 54 | base >= 4 && < 5, 55 | tasty, 56 | --tasty-program, 57 | tasty-golden, 58 | process, 59 | filepath 60 | 61 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | 3 | sudo: true 4 | 5 | matrix: 6 | include: 7 | - env: BUILD=stack STACK_YAML=stack.yaml 8 | 9 | addons: 10 | apt: 11 | packages: 12 | - wget 13 | - libgmp-dev 14 | - libffi6 15 | - libc6:i386 16 | 17 | cache: 18 | directories: 19 | - $HOME/.ghc 20 | - $HOME/.cabal 21 | - $HOME/.stack 22 | 23 | before_install: 24 | # update machine and install mlton 25 | - sudo apt-get -qq update 26 | - sudo apt-get install -y mlton 27 | # install Haskell stack 28 | - export PATH=$HOME/.local/bin:$PATH 29 | - ./.travis-setup.sh 30 | # install smackage 31 | - git clone git://github.com/standardml/smackage 32 | - cd smackage 33 | - make mlton 34 | - bin/smackage refresh 35 | - export PATH=$HOME/.smackage/bin:$PATH 36 | - bin/smackage get smackage 37 | - bin/smackage make smackage mlton 38 | - bin/smackage make smackage install 39 | - cd .. 40 | - rm -rf $HOME/smackage 41 | - mkdir -p $HOME/.mlton 42 | - echo "SMACKAGE $HOME/.smackage/lib" > $HOME/.mlton/mlb-path-map 43 | - echo "aplparse git git://github.com/melsman/aplparse.git" >> $HOME/.smackage/sources.local 44 | - echo "kitlib git git://github.com/melsman/kitlib.git" >> $HOME/.smackage/sources.local 45 | - smackage refresh 46 | - smackage get kitlib 47 | - smackage get aplparse 48 | # install apltail 49 | - git clone git://github.com/melsman/apltail 50 | - cd apltail 51 | - export MLCOMP="mlton -mlb-path-map $HOME/.mlton/mlb-path-map" 52 | - make aplt-mlton 53 | - cd .. 54 | - export TAIL_ROOT=$(pwd)/apltail 55 | # install Futhark 56 | - wget http://futhark-lang.org/releases/futhark-nightly-linux-x86_64.tar.xz 57 | - tar xf futhark-nightly-linux-x86_64.tar.xz 58 | - (cd futhark-nightly-linux-x86_64/ && PREFIX=$HOME/.local make install) 59 | 60 | install: 61 | # install tail2futhark 62 | - make install 63 | 64 | script: 65 | # execute tests 66 | - make test 67 | -------------------------------------------------------------------------------- /src/Tail2Futhark/Futhark/AST.hs: -------------------------------------------------------------------------------- 1 | module Tail2Futhark.Futhark.AST where 2 | 3 | newtype Program = Program [FunDecl] 4 | 5 | -- | Boolean is true if entry point. 6 | data FunDecl = FunDecl Bool Type Ident [TypeSizeParam] [Arg] Exp 7 | 8 | data DimDecl = AnyDim | NamedDim Ident | ConstDim Int 9 | deriving (Show, Eq, Ord) 10 | 11 | data Type = IntT 12 | | Int8T 13 | | F32T 14 | | F64T 15 | | BoolT 16 | | TupleT [Type] 17 | | ArrayT Type DimDecl 18 | | VarT Ident 19 | deriving (Show, Eq, Ord) 20 | 21 | rank :: Num a => Type -> a 22 | rank (ArrayT tp _) = 1 + rank tp 23 | rank _ = 0 24 | 25 | baseType :: Type -> Type 26 | baseType (ArrayT tp _) = baseType tp 27 | baseType tp = tp 28 | 29 | type Ident = String 30 | 31 | data TypeSizeParam = TypeParam Ident | SizeParam Ident 32 | 33 | type Arg = (Type, Ident) 34 | 35 | data Pattern = Ident Ident 36 | | TouplePat [Pattern] 37 | deriving (Show, Eq) 38 | 39 | data Constant = Int Integer 40 | | F32 Float 41 | | F64 Double 42 | | Char Char 43 | | Bool Bool 44 | | ArrayConstant [Constant] 45 | deriving (Show, Eq) 46 | 47 | data Operator = Plus | Mult | LessEq | GreaterEq | Less | Greater | Minus | Div | Eq | Mod | 48 | LogicAnd | LogicOr | Pow | And | Or | Xor | Shl | Shr | Concat 49 | deriving (Show, Eq) 50 | 51 | data Exp = Var Ident 52 | | Ascript Exp Type 53 | | Let Pattern Exp Exp 54 | | IfThenElse Exp Exp Exp 55 | | ForLoop Ident Exp Ident Exp Exp 56 | | Constant Constant 57 | | Index Exp [Exp] 58 | | Neg Exp 59 | | Array [Exp] 60 | | Tuple [Exp] 61 | | Project String Exp 62 | | BinApp Operator Exp Exp 63 | | FunCall Exp [Exp] 64 | | Rearrange [Integer] Exp 65 | | Unsafe Exp 66 | | Empty Type 67 | | Map Exp [Exp] 68 | | Filter Exp Exp 69 | | Scan Exp Exp Exp 70 | | Reduce Exp Exp Exp 71 | 72 | | Fn Type [Arg] Exp 73 | | Fun Ident [Exp] 74 | | Op Operator 75 | deriving (Show, Eq) 76 | 77 | -------------------------------------------------------------------------------- /tests/basic_tests/take.apl: -------------------------------------------------------------------------------- 1 | ⍝ --------------------------------------------- 2 | ⍝ Take operations on arrays of different ranks 3 | ⍝ --------------------------------------------- 4 | 5 | ⍝ Normal take 6 | V1 ← 3 ↑ 1 2 3 4 ⍝ --> 1 2 3 7 | T1 ← ∧/V1=1 2 3 8 | 9 | ⍝ Normal overtake 10 | V2 ← 6 ↑ 1 2 3 4 ⍝ --> 1 2 3 4 0 0 11 | T2 ← ∧/V2=1 2 3 4 0 0 12 | 13 | ⍝ Multi-dimensional take 14 | X ← 2 ↑ 4 5 ⍴ ⍳ 20 ⍝ --> 1 2 3 4 5 15 | ⍝ 6 7 8 9 10 16 | M1 ← 10 - X 17 | T3 ← ∧/∧/M1=2 5 ⍴ 9 8 7 6 5 4 3 2 1 0 18 | 19 | ⍝ Multi-dimensional overtake 20 | M2 ← 4 ↑ 2 5 ⍴ ⍳ 8 ⍝ --> 1 2 3 4 5 21 | ⍝ 6 7 8 1 2 22 | ⍝ 0 0 0 0 0 23 | ⍝ 0 0 0 0 0 24 | T4 ← ∧/∧/M2=4 5 ⍴ 1 2 3 4 5 6 7 8 1 2 0 0 0 0 0 0 0 0 0 0 25 | 26 | ⍝ Test of negative take 27 | V5 ← ¯2 ↑ 1 2 3 4 5 ⍝ --> 4 5 28 | T5 ← ∧/V5=4 5 29 | 30 | M6 ← ¯2 ↑ 4 2 ⍴ ⍳ 8 ⍝ --> 5 6 31 | ⍝ 7 8 32 | T6 ← ∧/∧/M6=2 2 ⍴ 5 6 7 8 33 | 34 | ⍝ Test of undertake 35 | V7 ← ¯6 ↑ 1 2 3 4 ⍝ --> 0 0 1 2 3 4 36 | T7 ← ∧/V7=0 0 1 2 3 4 37 | 38 | M8 ← ¯6 ↑ 4 2 ⍴ ⍳ 8 ⍝ --> 0 0 39 | ⍝ 0 0 40 | ⍝ 1 2 41 | ⍝ 3 4 42 | ⍝ 5 6 43 | ⍝ 7 8 44 | T8 ← ∧/∧/M8=6 2 ⍴ 0 0 0 0 1 2 3 4 5 6 7 8 45 | 46 | ⍝ Take from zilde 47 | 48 | V9 ← 3 ↑ ⍬ ⍝ --> [3](0,0,0) 49 | T9 ← ∧/V9=0 0 0 50 | 51 | V10 ← ¯3 ↑ ⍬ ⍝ --> [3](0,0,0) 52 | T10 ← ∧/V10=0 0 0 53 | 54 | ⍝ zero-takes 55 | 56 | V11 ← 0 ↑ 1 2 3 4 ⍝ --> [0]() 57 | T11 ← (0=≢V11) ∧ ∧/0=⍴ V11 58 | 59 | V12 ← 0 ↑ 4 2 ⍴ ⍳ 8 ⍝ --> [0,2]() 60 | T12 ← (0=≢V12) ∧ ∧/0 2=⍴ V12 61 | 62 | V13 ← 0 ↑ ⍬ ⍝ --> [0]() 63 | T13 ← (0=≢V13) ∧ ∧/0=⍴ V13 64 | 65 | ⍝ take from scalars 66 | 67 | V14 ← 3 ↑ 23 ⍝ --> [3](23,0,0) 68 | T14 ← ∧/V14=23 0 0 69 | 70 | V15 ← ¯3 ↑ 23 ⍝ --> [3](0,0,23) 71 | T15 ← ∧/V15=0 0 23 72 | 73 | V16 ← 1 ↑ 23 ⍝ --> [1](23) 74 | T16 ← ∧/V16=23 75 | 76 | V17 ← ¯1 ↑ 23 ⍝ --> [1](23) 77 | T17 ← ∧/V17=23 78 | 79 | V18 ← 0 ↑ 23 ⍝ --> [0]() 80 | T18 ← 1=⊃⍴⍴V18 81 | 82 | T19 ← 0=⊃⍴⍴3 83 | T ← T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15 T16 T17 T18 T19 84 | 85 | ⍝ ⎕ ← T 86 | 87 | +/T 88 | -------------------------------------------------------------------------------- /tests/basic_tests/Makefile: -------------------------------------------------------------------------------- 1 | include ../common.mk 2 | 3 | APLFILES=$(wildcard *.apl) 4 | FUTEXECS=$(APLFILES:%.apl=fut_%) 5 | TLEXECS=$(APLFILES:%.apl=tail_%) 6 | OUTFILES=$(APLFILES:%.apl=%.out) 7 | RESFILES=$(APLFILES:%.apl=%.res) 8 | TAILFILES=$(APLFILES:%.apl=%.tail) 9 | RESOPENCLFILES=$(APLFILES:%.apl=%.resopencl) 10 | 11 | OPENCL_DEVICE?=GeForce 12 | 13 | .PHONY: test 14 | test: $(RESFILES) 15 | @cat $(RESFILES) 16 | @echo "-------T E S T --- R E P O R T-------" 17 | @echo "Tests succeeded: `grep "OK" $(RESFILES) | wc -l` /`grep "Test" $(RESFILES) | wc -l`" 18 | @echo "Test errors: `grep "ERR" $(RESFILES) | wc -l` /`grep "Test" $(RESFILES) | wc -l`" 19 | @echo "-------------------------------------" 20 | @exit `grep "ERR" $(RESFILES) | wc -l` 21 | 22 | .PHONY: testopencl 23 | testopencl: $(RESOPENCLFILES) 24 | @cat $(RESOPENCLFILES) 25 | @echo "-------O p e n C L --- T E S T --- R E P O R T-------" 26 | @echo "Tests succeeded: `grep "OK" $(RESOPENCLFILES) | wc -l` /`grep "Test" $(RESOPENCLFILES) | wc -l`" 27 | @echo "Test errors: `grep "ERR" $(RESOPENCLFILES) | wc -l` /`grep "Test" $(RESOPENCLFILES) | wc -l`" 28 | @echo "-----------------------------------------------------" 29 | @exit `grep "ERR" $(RESOPENCLFILES) | wc -l` 30 | 31 | %.out: fut_% 32 | ./$< > $@ 33 | 34 | %.outopencl: futopencl_% 35 | ./$< -d $(OPENCL_DEVICE) > $@ 36 | 37 | %.res: %.out 38 | @(diff -aq $< $*.ok > /dev/null 2>&1; \ 39 | if [ $$? -eq 0 ]; then \ 40 | echo "Test $*.apl: OK" > $@ \ 41 | ; else \ 42 | if [ -e $*.ok ]; then \ 43 | echo "Test $*.apl: *** ERR: file $< differs from $*.ok ***" > $@ \ 44 | ; else \ 45 | echo "Test $*.apl: *** ERR: file $*.ok does not exist ***" > $@ \ 46 | ; fi \ 47 | ; fi) 48 | 49 | %.resopencl: %.outopencl 50 | @(diff -aq $< $*.ok > /dev/null 2>&1; \ 51 | if [ $$? -eq 0 ]; then \ 52 | echo "OpenCL Test $*.apl: OK" > $@ \ 53 | ; else \ 54 | if [ -e $*.ok ]; then \ 55 | echo "OpenCL Test $*.apl: *** ERR: file $< differs from $*.ok ***" > $@ \ 56 | ; else \ 57 | echo "OpenCL Test $*.apl: *** ERR: file $*.ok does not exist ***" > $@ \ 58 | ; fi \ 59 | ; fi) 60 | 61 | .PHONY: clean 62 | clean: 63 | rm -f *.fut tail_* fut_* *.res *.out *.comp futopencl_* *.outopencl *.resopencl *~ *.tail *.futu 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ** Warning: `tail2futhark` has not been kept fully up to date with recent changes in Futhark. However, it would not be a large job to fix it.** 2 | 3 | With `tail2Futhark` it is possible to compile APL programs - through [apltail](https://github.com/melsman/apltail) - to [Futhark](https://github.com/HIPERFIT/futhark) and thereby target GPGPU architectures supported by the Futhark project. 4 | 5 | ## Status 6 | 7 | [![Build Status](https://travis-ci.org/henrikurms/tail2futhark.svg?branch=master)](https://travis-ci.org/henrikurms/tail2futhark) 8 | 9 | ## Installation 10 | 11 | Use [Stack](http://haskellstack.org) to build the `tail2futhark` compiler. 12 | 13 | To get all the prerequisites for building (including, if necessary, 14 | the appropriate version of the Haskell compiler), run: 15 | 16 | stack setup 17 | 18 | *Notice that this command will not install anything system-wide and will have no 19 | effect outside the tail2futhark build directory*. Now, run the 20 | following command to build the `tail2futhark` compiler, including all 21 | dependencies: 22 | 23 | stack build 24 | 25 | You can install `tail2futhark` to your `$HOME/.local/bin` directory 26 | by running: 27 | 28 | stack install 29 | 30 | Make sure this directory is in your `$PATH`. Alternatively, just copy 31 | the binary to where you need it. 32 | 33 | ## Prerequisites 34 | 35 | To use `tail2futhark` and to test it, you need a working version of 36 | the [APLtail](https://github.com/melsman/apltail) compiler, which 37 | allows for compiling APL programs into TAIL programs, suitable for 38 | input to `tail2futhark`. 39 | 40 | __Notice: For installation instructions, you may consult the 41 | `.travis.yml` file, which documents the APLtail installation procedure 42 | for Linux boxes.__ 43 | 44 | ## Usage 45 | 46 | There are two ways to invoke `tail2futhark`, corresponding to whether 47 | you want to compile a program with a `main` function, or a library 48 | with multiple entry points. In the former case, run 49 | 50 | tail2futhark prog.tail -o prog.fut 51 | 52 | which results in a Futhark program defining a `main` function. 53 | 54 | In the latter case, run 55 | 56 | tail2futhark --library prog1.tail ... progN.tail -o prog.fut 57 | 58 | This command results in a Futhark program with one entry point for every 59 | `.tail` file. The name of each entry point will match the name of the 60 | file, with `.tail` stripped off. 61 | 62 | ## APL to TAIL 63 | 64 | While stricly not the domain of `tail2futhark`, this is a handy 65 | command line for translating an APL file to a TAIL file suitable for 66 | consumption by `tail2futhark`: 67 | 68 | aplt -p_types -s_tail -c -o foo.tail ${TAIL_ROOT}/lib/prelude.apl foo.apl 69 | 70 | Here, `$TAIL_ROOT` must point to a checkout of the TAIL source 71 | repository. 72 | 73 | ## Testing 74 | 75 | To test the compiler, run the command: 76 | 77 | make test 78 | 79 | Yet an alternative is to run 80 | 81 | (cd tests/basic_tests; make testopencl) 82 | 83 | See the Prerequisites section for information about the required 84 | `apltail` compiler. 85 | -------------------------------------------------------------------------------- /lib/prelude.fut: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------- 2 | -- This Futhark program is generated automatically by tail2futhark. 3 | ------------------------------------------------------------------- 4 | 5 | import "/futlib/math" 6 | import "/futlib/array" 7 | 8 | let radix_sort_step_up [n] (p:([n]u32,[n]i32), digit_n:i32) : ([n]u32,[n]i32) = 9 | let (xs,is) = p 10 | let bits = map (\(x:u32):i32 -> (i32.u32 x >>> digit_n) & 1) xs 11 | let bits_inv = map (\(b:i32):i32 -> 1 - b) bits 12 | let ps0 = scan (+) 0 bits_inv 13 | let ps0_clean = map2 (*) bits_inv ps0 14 | let ps1 = scan (+) 0 bits 15 | let ps0_offset = reduce (+) 0 bits_inv 16 | let ps1_clean = map (\(i:i32) : i32 -> i+ps0_offset) ps1 17 | let ps1_clean' = map2 (*) bits ps1_clean 18 | let ps = map2 (+) ps0_clean ps1_clean' 19 | let ps_actual = map (\(p:i32) : i32 -> p - 1) ps 20 | in (scatter (copy(xs)) ps_actual xs, 21 | scatter (copy(is)) ps_actual is) 22 | 23 | let radix_sort_step_down [n] (p:([n]u32,[n]i32), digit_n:i32) : ([n]u32,[n]i32) = 24 | let (xs,is) = p 25 | let bits = map (\(x:u32):i32 -> (i32.u32 x >>> digit_n) & 1) xs 26 | let bits_inv = map (\(b:i32):i32 -> 1 - b) bits 27 | let ps1 = scan (+) 0 bits 28 | let ps1_offset = reduce (+) 0 bits 29 | let ps1_clean = map2 (*) bits ps1 30 | let ps0 = scan (+) 0 bits_inv 31 | let ps0_clean = map (\(i:i32) : i32 -> i+ps1_offset) ps0 32 | let ps0_clean' = map2 (*) bits_inv ps0_clean 33 | let ps = map2 (+) ps1_clean ps0_clean' 34 | let ps_actual = map (\(p:i32) : i32 -> p - 1) ps 35 | in (scatter (copy(xs)) ps_actual xs, 36 | scatter (copy(is)) ps_actual is) 37 | 38 | let radix_sort_up [n] (xs: [n]u32) : ([n]u32,[n]i32) = 39 | let is = iota(n) in 40 | let is = map (+1) is in 41 | loop (p:([n]u32,[n]i32)) = (xs,is) for i < 32 do 42 | radix_sort_step_up(p,i) 43 | 44 | let radix_sort_down [n] (xs: [n]u32) : ([n]u32,[n]i32) = 45 | let is = iota(n) in 46 | let is = map (+1) is in 47 | loop (p:([n]u32,[n]i32)) = (xs,is) for i < 32 do 48 | radix_sort_step_down(p,i) 49 | 50 | let grade_up [n] (xs: [n]i32) : [n]i32 = 51 | let xs = map u32.i32 xs in 52 | let (_,is) = radix_sort_up xs in is 53 | 54 | let grade_down [n] (xs: [n]i32) : [n]i32 = 55 | let xs = map u32.i32 xs in 56 | let (_,is) = radix_sort_down xs in is 57 | 58 | let sgmScanSum [n] (vals:[n]i32) (flags:[n]bool) : [n]i32 = 59 | let pairs = scan ( \((v1,f1):(i32,bool)) ((v2,f2):(i32,bool)) : (i32,bool) -> 60 | let f = f1 || f2 61 | let v = if f2 then v2 else v1+v2 62 | in (v,f) ) (0,false) (zip vals flags) 63 | let (res,_) = unzip pairs 64 | in res 65 | 66 | let replIdx [n] (reps:[n]i32) : []i32 = 67 | let tmp = scan (+) 0 reps 68 | let sers = map (\(i:i32):i32 -> if i == 0 then 0 else unsafe tmp[i-1]) (iota(n)) 69 | let m = unsafe tmp[n-1] 70 | let tmp2 = scatter (replicate m 0) sers (iota(n)) 71 | let flags = map (>0) tmp2 72 | let res = sgmScanSum tmp2 flags 73 | in res 74 | 75 | let negi (x: i32): i32 = 76 | -x 77 | 78 | let absi (x: i32): i32 = 79 | if x <= 0 80 | then -x 81 | else x 82 | 83 | let mini (x: i32) (y: i32): i32 = 84 | if x <= y 85 | then x 86 | else y 87 | 88 | let maxi (x: i32) (y: i32): i32 = 89 | if x <= y 90 | then y 91 | else x 92 | 93 | let eqb (x: bool) (y: bool): bool = 94 | ! (x || y) || (x && y) 95 | 96 | let xorb (x: bool) (y: bool): bool = 97 | ! (x && y) && (x || y) 98 | 99 | let nandb (x: bool) (y: bool): bool = 100 | ! (x && y) 101 | 102 | let norb (x: bool) (y: bool): bool = 103 | ! (x || y) 104 | 105 | let neqi (x: i32) (y: i32): bool = 106 | x != y 107 | 108 | let neqd (x: f32) (y: f32): bool = 109 | x != y 110 | 111 | let resi (x: i32) (y: i32): i32 = 112 | if x == 0 113 | then y 114 | else (y % x) 115 | 116 | let frotate 't (i: i32) (xs: []t) = rotate i xs 117 | -------------------------------------------------------------------------------- /doc/references.bib: -------------------------------------------------------------------------------- 1 | @inproceedings{ElsmanDybdal:Array:2014, 2 | author = {Martin Elsman and Martin Dybdal}, 3 | title = {Compiling a Subset of {APL} Into a Typed Intermediate Language}, 4 | booktitle = {Proceedings of the 1st ACM SIGPLAN International Workshop on Libraries, Languages and Compilers for Array Programming}, 5 | series = {ARRAY'14}, 6 | year = {2014}, 7 | month = "June", 8 | publisher = {ACM} 9 | } 10 | 11 | @inproceedings{Array:2015, 12 | author = {Michael Budde and Martin Dybdal and Martin Elsman}, 13 | title = {Compiling {APL} to Accelerate through a Typed Array Intermediate Language.}, 14 | booktitle = {Proceedings of the 2nd ACM SIGPLAN International Workshop on Libraries, Languages and Compilers for Array Programming}, 15 | series = {ARRAY’15}, 16 | year = {2015}, 17 | month = "June", 18 | publisher = {ACM}, 19 | } 20 | 21 | @techreport{APLACC, 22 | author = {Michael Budde}, 23 | title = {Compiling {APL} to Accelerate Through a Typed {IL}}, 24 | institution = {Department of Computer Science, University of Copenhagen}, 25 | type = {MSc project}, 26 | year = {2014}, 27 | month = {November}, 28 | } 29 | 30 | @mastersthesis{TroelsHenriksen, 31 | author = "Troels Henriksen", 32 | title = "Exploiting Functional Invariants to Optimise Parallelism: a dataflow approach", 33 | school = "Department of Computer Science, University of Copenhagen", 34 | type = "MSc thesis", 35 | year = "2014", 36 | month = "February", 37 | } 38 | 39 | @book{TorbenMogensen, 40 | author = "Torben Mogensen", 41 | title = "Introduction to Compiler Design", 42 | publisher = "Springer", 43 | year = "2011", 44 | } 45 | 46 | @book{APLbook, 47 | author = "Kenneth E. Iverson", 48 | title = "A programming Language", 49 | publisher = "John Wiley and Sons", 50 | year = "1962", 51 | } 52 | 53 | @book{APLDyalog, 54 | author = "Bernard Legrand", 55 | title = "Mastering Dyalog APL: A Complete Introduction to Dyalog APL", 56 | publisher = "Dyalog Limited", 57 | year = "2009", 58 | } 59 | 60 | @inproceedings{T.Henriksen&C.Oancea, 61 | author = "Troels Henriksen and Cosmin E. Oancea", 62 | title = "Bounds Checking: An Instance of Hybrid Analysis", 63 | booktitle = "ACM SIGPLAN International Workshop on Libraries, Languages and Compilers for Array Programming", 64 | series = {ARRAY'14}, 65 | year = {2014}, 66 | month = "September", 67 | publisher = {ACM} 68 | } 69 | 70 | @inproceedings{T2graph, 71 | author = "Troels Henriksen and Cosmin E. Oancea", 72 | title = "A T2 Graph-Reduction Approach To Fusion", 73 | booktitle = "2nd ACM SIGPLAN Workshop on Functional High-Performance Computing", 74 | year = {2013}, 75 | month = "September", 76 | publisher = {ACM} 77 | } 78 | 79 | @inproceedings{Hybrid, 80 | author = "Troels Henriksen and Martin Elsman and Cosmin E. Oancea", 81 | title = "Size Slicing - A Hybrid Approach to Size Inference in Futhark", 82 | booktitle = "Proceedings of the 3rd ACM SIGPLAN workshop on Functional High-Performance Computing", 83 | year = {2014}, 84 | month = "September", 85 | publisher = {ACM}, 86 | } 87 | 88 | @misc{MartinElsmanNotation, 89 | author = {Martin Elsman}, 90 | title = {{Optimising Typed Programs}}, 91 | howpublished = "http://www.elsman.com/pdf/optimiser.pdf", 92 | year = {1998}, 93 | note = "[Online; accessed 19-April-2015]" 94 | } 95 | 96 | @misc{parsec, 97 | author = "Daan Leijen and Paolo Martini", 98 | title = {{The parsec package}}, 99 | howpublished = "https://hackage.haskell.org/package/parsec", 100 | note = "[Online; accessed 19-April-2015]" 101 | } 102 | 103 | @misc{tasty, 104 | author = "Roman Cheplyaka", 105 | title = {{The tasty package}}, 106 | howpublished = "https://hackage.haskell.org/package/tasty", 107 | note = "[Online; accessed 19-April-2015]" 108 | } 109 | 110 | @misc{tasty-golden, 111 | author = "Roman Cheplyaka", 112 | title = {{The tasty-golden package}}, 113 | howpublished = "https://hackage.haskell.org/package/tasty-golden", 114 | note = "[Online; accessed 19-April-2015]" 115 | } 116 | 117 | @misc{cabal, 118 | author = "Isaac Jones and Duncan Coutts", 119 | title = {{The Cabal package}}, 120 | howpublished = "https://hackage.haskell.org/package/Cabal", 121 | note = "[Online; accessed 19-April-2015]" 122 | } -------------------------------------------------------------------------------- /tests/benchmarks/life/rle.sml: -------------------------------------------------------------------------------- 1 | (* Run-Length-Encoded file translator *) 2 | 3 | (* Translates to Futhark array syntax *) 4 | 5 | fun println s = print (s ^ "\n") 6 | fun eprintln s = TextIO.output(TextIO.stdErr, s ^ "\n") 7 | 8 | fun printusage () = 9 | (println "rle [OPTIONS] < file.in > file.out"; 10 | println "OPTIONS:"; 11 | println " --help: print usage information and exit"; 12 | println " --flat: print a flat vector preceeded by a\n\ 13 | \ 2-element dimension vector (x,y)"; 14 | println " --verbose: print debugging information") 15 | 16 | fun die s = (eprintln s; OS.Process.exit(1)) 17 | 18 | local val verbose = ref false 19 | val flat = ref false 20 | in fun msg s = if !verbose then eprintln s else () 21 | fun flatFlag() = !flat 22 | fun process nil = nil 23 | | process ("--verbose"::rest) = (verbose:=true; process rest) 24 | | process ("--flat"::rest) = (flat:=true; process rest) 25 | | process ("--help"::_) = (printusage(); OS.Process.exit(0)) 26 | | process xs = xs 27 | end 28 | 29 | val args = process(CommandLine.arguments()) 30 | 31 | val file = TextIO.inputAll TextIO.stdIn 32 | val lines = String.tokens (fn #"\n" => true | #"\r" => true 33 | | _ => false) file 34 | 35 | val lines = List.filter (fn l => size l > 0 andalso String.sub(l,0) <> #"#") lines (* drop comments *) 36 | 37 | fun readAssgn var0 s = 38 | case String.tokens (fn c => c = #"=") s of 39 | [var,value] => 40 | (case Int.fromString value of 41 | SOME x => x 42 | | NONE => die ("expecting integer in assignment for " ^ var0 ^ "(" ^ var ^ ")")) 43 | | _ => die ("readAssgn.problem with assignment for " ^ var0 ^ " - " ^ s) 44 | 45 | val (x,y,lines) = 46 | case lines of 47 | header :: lines => 48 | (case String.tokens (fn c => c = #",") header of 49 | xassgn::yassgn::_ => 50 | let val x = readAssgn "x" xassgn 51 | val y = readAssgn "y" xassgn 52 | in (x,y,lines) 53 | end 54 | | _ => die "expecting header with assignments for x and y") 55 | | _ => die "expecting file with at least one line (except comments)" 56 | 57 | fun repeat n v acc = 58 | if n <= 0 then acc 59 | else repeat (n-1) v (v::acc) 60 | 61 | fun transLines (nil,n,acc,rows,argopt) = die "Premature end of file - expects the ! character" 62 | | transLines (l::ls,n,acc,rows,argopt) = 63 | let val cs = explode l 64 | fun readint0 (nil,NONE) = NONE 65 | | readint0 (nil,SOME v) = SOME (v,nil) 66 | | readint0 (c::cs,NONE) = 67 | if Char.isDigit c then readint0(cs,SOME [c]) 68 | else NONE 69 | | readint0 (c::cs,SOME l) = 70 | if Char.isDigit c then readint0(cs,SOME (c::l)) 71 | else SOME (l,c::cs) 72 | fun readint cs = case readint0 (cs,NONE) of 73 | NONE => NONE 74 | | SOME (l,cs') => case Int.fromString (implode (rev l)) of 75 | NONE => NONE 76 | | SOME i => SOME (i,cs') 77 | fun unArgOpt NONE = 1 78 | | unArgOpt (SOME i) = i 79 | fun loop (cs,n,acc,rows,argopt) = 80 | case cs of 81 | nil => transLines(ls,n,acc,rows,argopt) 82 | | #"$" :: cs => loop(cs,0,nil,List.rev(repeat (x-n) 0 acc)::rows,NONE) 83 | | #"!" :: _ => List.rev(repeat (x-n) 0 acc) :: rows 84 | | #"b" :: cs => 85 | let val i = unArgOpt argopt 86 | in loop (cs,n+i,repeat i 0 acc,rows,NONE) 87 | end 88 | | #"o" :: cs => 89 | let val i = unArgOpt argopt 90 | in loop (cs,n+i,repeat i 1 acc,rows,NONE) 91 | end 92 | | c::_ => case readint cs of 93 | SOME (i,cs) => loop(cs,n,acc,rows,SOME i) 94 | | NONE => die ("Unrecognized character '" ^ String.str c ^ "' (" ^ Char.toString c ^ ")") 95 | in loop (explode l,n,acc,rows,argopt) 96 | end 97 | 98 | val res = transLines (lines,0,nil,nil,NONE) 99 | 100 | fun spar s = "[" ^ s ^ "]" 101 | 102 | fun layoutRow row = spar(String.concatWith "," (List.map Int.toString row)) 103 | 104 | fun flatten nil = nil 105 | | flatten (x::xs) = x @ flatten xs 106 | 107 | val () = 108 | if flatFlag() then 109 | (println (spar(Int.toString x ^ "," ^ Int.toString y)); 110 | println(layoutRow(flatten res))) 111 | else 112 | println(spar(String.concatWith "," (List.map layoutRow res))) 113 | 114 | val () = eprintln "Done!" 115 | -------------------------------------------------------------------------------- /src/Tail2Futhark/Futhark/Pretty.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -fno-warn-orphans #-} 2 | module Tail2Futhark.Futhark.Pretty (pretty) where 3 | 4 | import Tail2Futhark.Futhark.AST 5 | import Text.PrettyPrint.Mainland.Class 6 | import Text.PrettyPrint.Mainland hiding (pretty) 7 | import qualified Text.PrettyPrint.Mainland as PP 8 | 9 | -- | Prettyprint a value, wrapped to 80 characters. 10 | pretty :: Pretty a => a -> String 11 | pretty = PP.pretty 80 . ppr 12 | 13 | instance Pretty Program where 14 | ppr (Program fundecs) = 15 | stack . map ppr $ fundecs 16 | 17 | instance Pretty FunDecl where 18 | ppr (FunDecl entry tp ident tsparams args body) = 19 | fun' 20 | <+> text ident 21 | <+> tsparams' <+> args' 22 | <> text ":" <+> ppr tp 23 | <+> equals 24 | indent 2 (ppr body) 25 | where fun' = text $ if entry then "entry" else "let" 26 | args' = case args of 27 | [] -> parens mempty 28 | _ -> spread (map (parens . ppArg) args) 29 | tsparams' = spread $ map ppr tsparams 30 | 31 | instance Pretty TypeSizeParam where 32 | ppr (SizeParam x) = brackets $ text x 33 | ppr (TypeParam x) = text "'" <> text x 34 | 35 | commaList :: [Doc] -> Doc 36 | commaList = parens . commasep 37 | brackList :: [Doc] -> Doc 38 | brackList = brackets . commasep 39 | brackExps :: [Exp] -> Doc 40 | brackExps = brackList . map ppr 41 | 42 | instance Pretty Type where 43 | ppr IntT = text "i32" 44 | ppr Int8T = text "i8" 45 | ppr F32T = text "f32" 46 | ppr F64T = text "f64" 47 | ppr BoolT = text "bool" 48 | ppr (VarT s) = text s 49 | ppr (ArrayT at d) = brackets (ppr d) <> ppr at 50 | ppr (TupleT ts) = parens $ commasep $ map ppr ts 51 | 52 | instance Pretty DimDecl where 53 | ppr AnyDim = mempty 54 | ppr (NamedDim d) = ppr d 55 | ppr (ConstDim d) = ppr d 56 | 57 | instance Pretty Exp where 58 | ppr (Var ident) = text ident 59 | ppr (Ascript e t) = ppr e <+> colon <+> ppr t 60 | ppr (Let pat exp1 exp2) = text "let" <+> ppPat pat <+> equals <+> align (ppr exp1) <+> text "in" ppr exp2 61 | ppr (IfThenElse e1 e2 e3) = text "if" <+> ppr e1 text "then" <+> ppr e2 text "else" <+> ppr e3 62 | ppr (Unsafe e) = text "unsafe" <+> ppr e 63 | ppr (ForLoop merge merge_init i bound loopbody) = 64 | text "loop" <+> text merge <+> text "=" <+> ppr merge_init <+> text "for" <+> text i <+> text "<" <+> ppr bound <+> text "do" 65 | indent 2 (ppr loopbody) 66 | ppr (Constant c) = ppr c 67 | ppr (Neg e) = text "-" <> ppr e 68 | ppr (Index (Var v) exps) = ppr v <> brackExps exps 69 | ppr (Index e exps) = parens (ppr e) <> brackExps exps 70 | ppr (Array exps) = brackExps exps 71 | ppr (Tuple exps) = parens $ commasep $ map ppr exps 72 | ppr (Project f e) = ppr e <> text "." <> text f 73 | ppr (BinApp op e1 e2) = parens $ ppr e1 <+> ppOp op <+> ppr e2 74 | ppr (FunCall f exps) = ppr f <+> spread (map (parens . ppr) exps) 75 | ppr (Rearrange perm e) = text "rearrange" <+> parens (commasep $ map ppr perm) <+> parens (ppr e) 76 | ppr (Empty tp) = text "empty" <> parens (ppr tp) 77 | ppr (Map k es) = ppSOAC1 ("map" ++ show (length es)) k es 78 | ppr (Filter k e) = ppSOAC1 "filter" k [e] 79 | ppr (Scan k e1 e2) = ppSOAC2 "scan" k e1 e2 80 | ppr (Reduce k e1 e2) = ppSOAC2 "reduce" k e1 e2 81 | 82 | ppr (Fn tp args body) = 83 | parens $ 84 | text "\\" <+> (spread $ map (parens . ppArg) args) <> 85 | text ":" <+> ppr tp <+> text "->" 86 | ppr body 87 | ppr (Fun ident []) = text ident 88 | ppr (Fun ident exps) = parens $ text ident <+> (commaList . map ppr $ exps) 89 | ppr (Op op) = parens $ ppOp op 90 | 91 | ppSOAC1 :: String -> Exp -> [Exp] -> Doc 92 | ppSOAC1 v k es = text v <+> ppr k <+> spread (map (parens . ppr) es) 93 | 94 | ppSOAC2 :: String -> Exp -> Exp -> Exp -> Doc 95 | ppSOAC2 v k e1 e2 = text v <+> ppr k <+> parens (ppr e1) <+> parens (ppr e2) 96 | 97 | ppOp :: Operator -> Doc 98 | ppOp op = text $ case op of 99 | Plus -> "+" 100 | Minus -> "-" 101 | LessEq -> "<=" 102 | Mult -> "*" 103 | Div -> "/" 104 | Eq -> "==" 105 | Mod -> "%" 106 | Greater -> ">" 107 | Less -> "<" 108 | GreaterEq -> ">=" 109 | LogicAnd -> "&&" 110 | LogicOr -> "||" 111 | Pow -> "**" 112 | Or -> "|" 113 | Xor -> "^" 114 | And -> "&" 115 | Shl -> ">>" 116 | Shr -> "<<" 117 | Concat -> "++" 118 | --XOr -> "^" 119 | 120 | instance Pretty Constant where 121 | ppr (Int x) = integer x 122 | ppr (F32 f) = text (show f) <> text "f32" 123 | ppr (F64 f) = text (show f) <> text "f64" 124 | ppr (Char c) = text $ show c 125 | ppr (Bool b) = text (if b then "true" else "false") 126 | ppr (ArrayConstant arr) = brackets . commasep . map ppr $ arr 127 | 128 | -- Arguments -- 129 | ppArg :: (Type, String) -> Doc 130 | ppArg (tp,ident) = text ident <> text ":" <+> ppr tp 131 | 132 | -- Pattern -- 133 | ppPat :: Pattern -> Doc 134 | ppPat (Ident ident) = text ident 135 | ppPat (TouplePat pat) = parens . commasep . map ppPat $ pat 136 | -------------------------------------------------------------------------------- /tests/basic_tests/mandel.ok: -------------------------------------------------------------------------------- 1 | [[32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 35i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 35i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 32i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 35i32, 35i32, 35i32, 32i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 35i32, 35i32, 35i32, 32i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 35i32, 32i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 35i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 35i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 35i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32], [32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32, 32i32]] 2 | -------------------------------------------------------------------------------- /src/Tail2Futhark/TAIL/Parser.hs: -------------------------------------------------------------------------------- 1 | -- | Originally from APLAcc by Michael Budde 2 | module Tail2Futhark.TAIL.Parser (parseFile, parseString) where 3 | 4 | import Control.Applicative 5 | import System.IO (Handle, hGetContents) 6 | import Control.Monad (void) 7 | import Text.Parsec hiding (Empty, (<|>)) 8 | import Text.Parsec.String 9 | import qualified Text.Parsec.Token as Token 10 | 11 | import Prelude 12 | 13 | import Tail2Futhark.TAIL.AST 14 | 15 | 16 | parseFile :: Handle -> String -> IO Program 17 | parseFile handle filename = 18 | do str <- hGetContents handle 19 | case parse program filename str of 20 | Left e -> error $ show e 21 | Right r -> return r 22 | 23 | 24 | tailDef :: Token.LanguageDef u 25 | tailDef = Token.LanguageDef { 26 | Token.commentStart = "(*" 27 | , Token.commentEnd = "*)" 28 | , Token.commentLine = "" 29 | , Token.nestedComments = False 30 | , Token.identStart = letter 31 | , Token.identLetter = alphaNum <|> char '_' 32 | , Token.opStart = oneOf "" 33 | , Token.opLetter = oneOf "" 34 | , Token.reservedOpNames = [] 35 | , Token.reservedNames = [ "let", "in", "int", "double", "fn", "inf" , "tt", "ff"] 36 | , Token.caseSensitive = True 37 | } 38 | 39 | lexer :: Token.TokenParser u 40 | lexer = Token.makeTokenParser tailDef 41 | 42 | charlit :: Parser Char 43 | identifier :: Parser String 44 | reserved, symbol :: String -> Parser () 45 | parens, brackets, angles, braces, lexeme :: Parser a -> Parser a 46 | decimal :: Parser Integer 47 | float :: Parser Double 48 | whitespace, comma, colon :: Parser () 49 | 50 | identifier = Token.identifier lexer 51 | reserved = Token.reserved lexer 52 | charlit = Token.charLiteral lexer 53 | parens = Token.parens lexer 54 | brackets = Token.brackets lexer 55 | angles = Token.angles lexer 56 | braces = Token.braces lexer 57 | whitespace = Token.whiteSpace lexer 58 | decimal = Token.decimal lexer 59 | float = Token.float lexer 60 | lexeme = Token.lexeme lexer 61 | comma = void $ Token.comma lexer 62 | colon = void $ Token.colon lexer 63 | symbol = void . Token.symbol lexer 64 | 65 | program :: Parser Program 66 | program = 67 | do whitespace 68 | prog <- expr 69 | eof 70 | return prog 71 | 72 | ----------------- 73 | -- Expression 74 | 75 | expr :: Parser Exp 76 | expr = projExpr 77 | <|> opExpr 78 | <|> arrayExpr 79 | <|> letExpr 80 | <|> fnExpr 81 | <|> valueExpr 82 | "expression" 83 | 84 | valueExpr :: Parser Exp 85 | valueExpr = try (X <$> signed float <* (symbol "j" <|> symbol "J") <*> signed float) 86 | <|> try (D <$> lexeme float) 87 | <|> I <$> lexeme decimal 88 | <|> try (reserved "inf" >> return Inf) 89 | <|> (char '-' >> Neg <$> valueExpr) 90 | <|> C <$> charlit 91 | <|> B <$> ((reserved "tt" >> return True) <|> (reserved "ff" >> return False)) 92 | <|> Var <$> identifier 93 | <|> Ts <$> try (parens (expr `sepBy1` comma)) 94 | "number or identifier" 95 | 96 | signed :: Num num => Parser num -> Parser num 97 | signed p = (char '-' >> negate <$> p) <|> p 98 | 99 | arrayExpr :: Parser Exp 100 | arrayExpr = Vc <$> brackets (sepBy (opExpr <|> valueExpr) comma) 101 | 102 | letExpr :: Parser Exp 103 | letExpr = 104 | do reserved "let" 105 | (ident, typ) <- typedIdent 106 | symbol "=" 107 | e1 <- expr 108 | reserved "in" 109 | e2 <- expr 110 | return $ Let ident typ e1 e2 111 | 112 | instanceDecl :: Parser InstDecl 113 | instanceDecl = braces $ 114 | do btyps <- brackets $ sepBy basicType comma 115 | comma 116 | ranks <- brackets $ sepBy (lexeme decimal) comma 117 | return (btyps, ranks) 118 | 119 | projExpr :: Parser Exp 120 | projExpr = 121 | do symbol "Prj" 122 | n <- optionMaybe $ braces $ lexeme decimal 123 | (i, e) <- parens $ (,) <$> lexeme decimal <*> (comma *> expr) 124 | return $ Prj n i e 125 | 126 | opExpr :: Parser Exp 127 | opExpr = 128 | do ident <- try $ do i <- identifier 129 | void $ lookAhead $ oneOf "({" 130 | return i 131 | instDecl <- optionMaybe instanceDecl 132 | args <- parens $ sepBy expr comma 133 | return $ Op ident instDecl args 134 | 135 | fnExpr :: Parser Exp 136 | fnExpr = 137 | do reserved "fn" 138 | (ident, typ) <- typedIdent 139 | symbol "=>" 140 | e <- expr 141 | return $ Fn ident typ e 142 | 143 | typedIdent :: Parser (Ident, Type) 144 | typedIdent = 145 | do ident <- identifier 146 | colon 147 | typ <- typeExpr 148 | return (ident, typ) 149 | 150 | ------------------ 151 | -- Types 152 | 153 | typeExpr :: Parser Type 154 | typeExpr = arrayType <|> vectorType <|> tupleType "type" 155 | --typeExpr = liftM (foldr1 FunT) $ 156 | -- sepBy1 (arrayType <|> vectorType "type") (symbol "->") 157 | 158 | arrayType :: Parser Type 159 | arrayType = ArrT <$> brackets basicType <*> rank 160 | 161 | -- vectortype as replacement for shapeType 162 | vectorType :: Parser Type 163 | vectorType = VecT <$> angles basicType <*> rank 164 | <|> (try (symbol "SV") >> parens (SV <$> basicType <* comma <*> rank)) 165 | <|> (try (symbol "S") >> parens (S <$> basicType <* comma <*> rank)) 166 | "vector type" 167 | 168 | tupleType :: Parser Type 169 | tupleType = TupT <$> parens (typeExpr `sepBy1` symbol "*") 170 | 171 | --shapeType :: Parser Type 172 | --shapeType = shape "Sh" ShT 173 | -- <|> shape "Si" SiT 174 | -- <|> shape "Vi" ViT 175 | -- "shape type" 176 | -- where shape name con = try (symbol name) >> liftM con (parens rank) 177 | 178 | rank :: Parser Rank 179 | rank = R <$> lexeme decimal 180 | -- <|> (liftM Rv identifier) Unsupported 181 | "rank" 182 | 183 | basicType :: Parser BType 184 | basicType = (reserved "int" >> return IntT) 185 | <|> (reserved "double" >> return DoubleT) 186 | <|> (reserved "bool" >> return BoolT) 187 | <|> (reserved "char" >> return CharT) 188 | <|> (reserved "complex" >> return ComplexT) 189 | <|> (char '\'' >> Btyv <$> many1 alphaNum) 190 | "basic type" 191 | 192 | ------------------- 193 | -- Debug functions 194 | 195 | parseString :: Parser a -> String -> a 196 | parseString parser str = 197 | case parse parser "" str of 198 | Left e -> error $ show e 199 | Right r -> r 200 | 201 | -------------------------------------------------------------------------------- /tests/benchmarks/life/3enginecordershiprake.rle: -------------------------------------------------------------------------------- 1 | #N 3-engine Cordership rake 2 | #O Jason Summers 3 | #C A period 240 c/2 orthogonal 3-engine Cordership rake created on Jan 4 | #C uary 19, 2004. 5 | #C www.conwaylife.com/wiki/index.php?title=3-engine_Cordership_rake 6 | x = 461, y = 424, rule = b3/s23 7 | 142b2o317b$126b2o13b2ob2o315b$125b4o13b4o315b$124b2ob2o14b2o316b$125b 8 | 2o334b$147bo313b$146b3o312b$130bo11bo3b2obo311b$128b4o10bo6bo311b$127b 9 | ob5o14bo6bo305b$126b2o6bo18b2o306b$127b3obo3bo18b2o305b$128b3o3bo326b$ 10 | 133bo327b$160bo5b2o293b$126b2o30b2o5b2ob3o290b$125b4o4b4o22b2o5b5o290b 11 | $124b2ob2o4bo3bo3bo2bo22b3o291b$125b2o6bo6bo320b$134bo2bo2bo3bo20bo 12 | 295b$140b4o9b2o8b2o296b$146b3o5b2o8b2o295b$146b2ob2o6b3o301b$146b3o5b 13 | 2o305b$140b4o9b2o306b$140bo3bo316b$140bo320b$141bo2bo316b$159bo2bo298b 14 | $158bo302b$158bo3bo298b$100b2o56b4o299b$99b4o68bo289b$98b2ob2o68bo289b 15 | $82b2o15b2o58b3o3bo295b$81b2ob2o72b5o2bo7bo287b$82b4o71b2ob4obo7bo287b 16 | $83b2o73b2o301b$103bo357b$97b2o3b3o356b$85b3o9b3ob5o355b$84b2o3bo9b3o 17 | 8bobo348b$83b2o2bobo9b3o8b2o46b4o299b$84bo5bo9bo10bo46bo3bo298b$85b2o 18 | 2bo11bo56bo302b$89bo34b3o32bo2bo298b$87bo27bobo5b5o333b$91bo2bo20b2o5b 19 | 2ob3o333b$82b2o6bo25bo6b2o336b$81b2ob2o4bo3bo366b$82b4o4b4o3b4o360b$ 20 | 83b2o12bo3bo9bo8bobo338b$97bo11b2o9b2o14bo324b$98bo2bo2b2o5b3o7bo12bo 21 | 3bo322b$103b3o6b3o18bo327b$98bo2bo2b2o5b3o19bo4bo322b$97bo11b2o22b5o 22 | 323b$97bo3bo9bo349b$97b4o360b2$115b2o344b$114b2ob2o342b$115b4o17b2o 23 | 323b$116b2o17b3o323b$117bo18b2o323b$115bo3bo2b2o13bobo321b$114bo5bob2o 24 | 14b2o321b$114bo5b4o337b$114b6o341b2$130b2o46bo2bo279b$129b2ob2o43bo 25 | 283b$130b4o5b2o36bo3bo279b$131b2o5b2ob4o15b4o13b4o280b$139b6o15bo3bo 26 | 296b$140b4o16bo300b$161bo2bo296b$181b3o277b$165bo10bobobo3bo276b$163b 27 | 3o10bo7bo27bobo10bo235b$162bo3bo15b2o5bo22b2o9b2o236b$162bo4b3o19bobo 28 | 21bo10b2o235b$162b2obob3o8bo10b2o270b$164bo3b2o34bo256b$165bobo34bo3bo 29 | 254b$194bo6bo259b$194bobo4bo4bo254b$160b4o5b2o23b2o5b5o255b$160bo3bo3b 30 | 2ob2o4b2o282b$160bo8b4o3b4o281b$161bo2bo5b2o3b2ob2o9bo9bo261b$176b2o 31 | 11bo9bobo259b$182bobo4b2o2bo5b2o260b$181b2o2bo7bo267b$182bobo4b2o2bo 32 | 267b$176b2o11bo271b$175b2ob2o9bo271b$176b4o281b$177b2o282b$68b2o125b2o 33 | 264b$66bo4bo122b4o263b$65bo127b2ob2o263b$57bo2bo4bo5bo68bo2bo50b2o265b 34 | $56bo8b6o68bo64bo256b$56bo3bo78bo3bo59bobo255b$56b4o62b4o13b4o55b2o2b 35 | 2ob3o6bo246b$42b4o76bo3bo66b12ob2o6bobo244b$41b7o4b2o68bo70bo7bo2bo9b 36 | 2o245b$40b2ob3ob2o2bobo69bo2bo66bo6b2o3b2o254b$41b2o3b2o2bo2b2o93bo45b 37 | o266b$50bo2bo73b2o19bobo45b2o263b$44b2o4bobo72b5o18b2o311b$42bo8bo72bo 38 | 4bo2b3obo63b2o259b$41bo82bo2b3o3bo3b2o60b4o258b$41bo3bo78b2o2bo7bobo 39 | 14bo44b2ob2o258b$41b4o81b2o7b2obo14bobo10bo32b2o260b$25b2o109b2o15b2o 40 | 9bo3bo292b$24b4o108bo26bo297b$23b2ob2o135bo4bo292b$24b2o5b2ob3o85b4o5b 41 | 2o25bo4b5o293b$30bo5b2o84bo3bo3b2ob2o4b2o17bobo300b$29b2o7bo10bo72bo8b 42 | 4o3b4o16b2o301b$30bo5b2o9bo2bo72bo2bo5b2o3b2ob2o9bo309b$24b2o5b2ob3o 43 | 10b2o89b2o11bo11b2o296b$9bo2bo5b2o3b2ob2o116bobo4b2o2bo7b2o296b$8bo8b 44 | 4o3b4o115b2o2bo7bo18b2o285b$8bo3bo3b2ob2o4b2o16b2o99bobo4b2o2bo17b2ob 45 | 3o282b$8b4o5b2o24bobo3b5o84b2o11bo22b5o282b$43bo5bo4bo82b2ob2o9bo23b3o 46 | 283b$49bo88b4o319b$50bo3bo21b2o61b2o320b$19b2o17b2o12bo22b2ob4o73b4o 47 | 302b$10b3o7b2o16bobo26b2o7b6o73bo3bo14b2o285b$10bo6bo2bo17bo27b2ob2o6b 48 | 4o74bo19b2o284b$10bobo6bo34b2o11b4o85bo17bo286b$11b2o3b2o34bo15b2o88b 49 | 2o301b$33b2o16bo6bo103b3o296b$33bo17bo8bo94b2o3b2o3bo295b$9bo2bo20bo 50 | 17b8obo93b2ob3obo2bo296b$8bo22b2o23b2o97b9o108bobo10bo175b$8bo3bo143b 51 | 4o112b2o9b2o176b$8b4o13b4o118bo22b4o99bo10b2o175b$25bo3bo22b2o94b2o20b 52 | o3bo286b$25bo25b2ob2o91b2o21bo8b6o276b$26bo2bo22b4o115bo2bo4bo5bo275b$ 53 | 35bo2bo14b2o124bo281b$34bo28b2o115bo4bo275b$34bo3bo7bo15b2o118b2o277b$ 54 | 34b4o4bo3b3o15bo396b$40b2o5b2o412b$40b3o6bo8bo402b$40b2o5b2o9b2o401b$ 55 | 34b4o4bo3b3o9b2o401b$28bo2bo2bo3bo7bo414b$19b2o6bo6bo426b$18b2ob2o4bo 56 | 3bo3bo2bo22b3o397b$19b4o4b4o22b2o5b5o396b$20b2o30b2o5b2ob3o396b$54bo5b 57 | 2o399b$27bo433b$22b3o3bo78b2o352b$21b3obo3bo18b2o56bobo352b$20b2o6bo 58 | 18b2o59bo156bo195b$21bob5o14bo6bo215bobo193b$22b4o10bo6bo75bo21bo123b 59 | 2o194b$24bo11bo3b2obo74b2o22bo131bo186b$40b3o75bobo19b3o131bobo184b$ 60 | 41bo10b3o219b2o185b$19b2o30b5o405b$18b2ob2o14b2o11b2ob3o405b$19b4o13b 61 | 4o11b2o408b$20b2o13b2ob2o421b$36b2o17b2o404b$54b3o31b4o369b$55b2o2b2o 62 | 26b9o365b$59b2o25b2ob3obo2bo364b$50b2o3bo31b2o3b2o3bo363b$49b2ob4obo 63 | 36b3o364b$50b7o33b2o369b$51b2o35bo15bo356b$87bo15bobo355b$37b4o46bo3bo 64 | 13bo355b$36b7o44b4o13bo356b$35b2ob3ob3o416b$36b2o3b2obo416b$69b4o388b$ 65 | 39b2o28bo3bo387b$37bo31bo7bo383b$36bo33bo2bo2b7o378b$36bo3bo34b2ob3o2b 66 | o10bo366b$36b4o30bo2bo2b7o9b3o366b$49bo19bo7bo15bobo365b$48b2o5b2o12bo 67 | 3bo387b$18b4o26bobo3b4o4b4o3b4o388b$18bo3bo10bo19b2ob2o4bo3bo22bo371b$ 68 | 18bo7b2o4bobo19b2o6bo25b2o5b2o364b$19bo2bo2b4o3bo2b2o26bo2bo21bobo3b2o 69 | b3o361b$24b2o3bo5bob2o56b5o361b$19bo2bo2b4o3bo2b2o59b3o362b$18bo7b2o4b 70 | obo29b2o18bo247bobo10bo115b$4b2o12bo3bo10bo22b2o7bo17b2o247b2o9b2o116b 71 | $3b4o4b4o3b4o17bo15b2o5bo2bo17bobo241bo5bo10b2o115b$2b2ob2o4bo3bo22b2o 72 | 16b2o4b3o263b2o131b$3b2o6bo26bobo3b2o11bo3b2o15bo248b2o132b$12bo2bo27b 73 | 2ob3o29bo382b$44b5o27bobo382b$16b2o16bo10b3o7b2o20bo383b$6b2o8b2o15b2o 74 | 19b4o18b2o383b$5bo2bo5bo3bo14bobo17b2ob2o403b$4b2o2bo4bo3bo36b2o15b2o 75 | 388b$5b2o2bo2bo4bo52b2ob2o386b$6b4o3bobo13bo41b4o210bobo173b$28b2o42b 76 | 2o212b2o173b$28bobo255bo174b$4b2o335b2o118b$3b4o334bobo117b$2b2ob2o63b 77 | 2o269bo119b$3b2o15b2o32b2o13b2ob2o387b$19b2ob2o29b4o13b4o387b$20b4o28b 78 | 2ob2o14b2o388b$21b2o30b2o406b2$325bo135b$67b2o4bo251bobo133b$56b2o9b2o 79 | 3b3o7bo38b2o198bo3b2o134b$55bo2bo12b2ob2o4b2o23b2o13b2ob2o197bo11bo 80 | 126b$54b2o2bo11b3ob3o4b2o21b4o13b4o195b3o11bobo124b$55b2o2bo11b2ob3o 81 | 26b2ob2o14b2o210b2o125b$56b4o12bobo29b2o355b$87bo373b$85b2o7b2o365b$ 82 | 54b2o30b2o5b2ob3o17b2o14bo328b$53b4o4b4o29b5o16bo2bo11b2o329b$52b2ob2o 83 | 4bo3bo3bo2bo22b3o8b2o13b3o7b2o328b$53b2o6bo6bo23bo12b2o5bo8bo2bo336b$ 84 | 62bo2bo2bo3bo11b2o4b2o14b2o4bo3bo3b2ob2o336b$68b4o11bo7b2o14bo3bo4bo 85 | 20bo323b$74b3o2b2o7bo25bo20b2o324b$74b3o2b2o8bo46b2o7b2o314b$74b3o2b2o 86 | 7bo8bo7b2o37b2ob3o311b$68b4o11bo11b2o7b4o4b4o29b5o133b2o38b2o136b$68bo 87 | 3bo11b2o10b2o5b2ob2o4bo3bo3bo2bo18bo3b3o135b2o38b2o135b$68bo35b2o6bo6b 88 | o20b2o141bo39bo137b$69bo2bo40bo2bo2bo3bo7bo9b2o318b$19b2o66bo2bo28b4o 89 | 4bo3b3o255b3o69b$18b4o64bo38b2o5b2o255bo71b$17b2ob2o64bo3bo34b3o6bo 90 | 255bo70b$b2o15b2o66b4o35b2o5b2o327b$2ob2o92bo21b4o4bo3b3o321b2o4b$b4o 91 | 90b2obo20bo3bo7bo190b3o129b2ob4o$2b2o83b3o10bo18bo202bo132b6o$26bobo 92 | 57b5o9bo19bo2bo28bo131bo38bo132b4ob$26b2o42b2o13b2ob4o5bo2bo37bo2bo8b 93 | 2o132b2o61b2o112b$4b4o3bobo13bo41b4o13b2o5b2o3bo38bo13b2o130bobo61bobo 94 | 111b$3b2o2bo2bo4bo52b2ob2o39bo24bo3bo205bo113b$2b2o2bo4bo3bo36b2o15b2o 95 | 39b2o25b4o320b$3bo2bo5bo3bo14bobo17b2ob2o50bo4b2o37bo310b$4b2o8b2o15b 96 | 2o19b4o18b2o24b2o4bo43bo243b5o62b$14b2o16bo10b3o7b2o20bo23b2ob2o2b2o 97 | 30b3o3bo249bo4bo61b$42b5o27bobo23b4ob3o29b5o2bo7bo241bo66b$10bo2bo27b 98 | 2ob3o29bo24b4o3bob2o24b2ob4obo7bo242bo3bo61b$b2o6bo26bobo3b2o11bo3b2o 99 | 15bo28bob5o25b2o258bo63b$2ob2o4bo3bo22b2o16b2o4b3o41b2ob2o352b$b4o4b4o 100 | 3b4o17bo15b2o5bo2bo17bobo22bo354b$2b2o12bo3bo10bo22b2o7bo17b2o19b2ob2o 101 | 354b$16bo7b2o4bobo29b2o18bo18b5o355b$17bo2bo2b4o3bo2b2o59b3o3b2ob3o 102 | 355b$22b2o3bo5bob2o56b5o3b2o358b$17bo2bo2b4o3bo2b2o26bo2bo21bobo3b2ob 103 | 3o363b$16bo7b2o4bobo19b2o6bo25b2o5b2o366b$16bo3bo10bo19b2ob2o4bo3bo22b 104 | o373b$16b4o26bobo3b4o4b4o3b4o390b$46b2o5b2o12bo3bo389b$47bo19bo7bo15bo 105 | bo367b$34b4o30bo2bo2b7o9b3o188b2o178b$34bo3bo34b2ob3o2bo10bo188bobo 106 | 177b$34bo33bo2bo2b7o200bo179b$35bo31bo7bo385b$37b2o28bo3bo389b$67b4o 107 | 390b$34b2o3b2obo418b$33b2ob3ob3o418b$34b7o44b4o13bo358b$35b4o46bo3bo 108 | 13bo357b$85bo15bobo357b$49b2o35bo15bo358b$48b7o33b2o371b$47b2ob4obo36b 109 | 3o366b$48b2o3bo31b2o3b2o3bo105b2o258b$57b2o25b2ob3obo2bo104bo4bo256b$ 110 | 53b2o2b2o26b9o104bo262b$52b3o31b4o100bo2bo4bo5bo256b$53b2o134bo8b6o 111 | 257b$40bo2bo145bo3bo267b$39bo9b2o138b4o268b$39bo3bo4b2ob3o121b4o282b$ 112 | 22b4o13b4o6b5o120b7o4b2o274b$22bo3bo23b3o120b2ob3ob2o2bobo274b$22bo93b 113 | obo55b2o3b2o2bo2b2o273b$23bo2bo89b2o65bo2bo274b$43b3o71bo25b2o32b2o4bo 114 | bo275b$27bo10bobobo3bo97b2o29bo8bo276b$25b3o10bo7bo59bo36bo30bo14b2o 115 | 270b$24bo3bo15b2o5bo52bobo67bo3bo10bobo269b$24bo4b3o19bobo51b2o67b4o 116 | 11bo139b3o129b$24b2obob3o8bo10b2o105b2o169bo131b$26bo3b2o34bo90b4o169b 117 | o130b$27bobo34bo3bo87b2ob2o9bo23b3o264b$56bo6bo93b2o11bo22b5o263b$56bo 118 | bo4bo4bo94bobo4b2o2bo17b2ob3o64b3o196b$22b4o5b2o23b2o5b5o94b2o2bo7bo 119 | 18b2o67bo198b$22bo3bo3b2ob2o4b2o122bobo4b2o2bo88bo197b$22bo8b4o3b4o 120 | 115b2o11bo8b2o106b2o172b$23bo2bo5b2o3b2ob2o19bo80bo2bo5b2o3b2ob2o9bo8b 121 | obo105bobo171b$38b2o5b2ob3o12bo77bo8b4o3b4o18bo107bo173b$44bo5b2o8bobo 122 | 78bo3bo3b2ob2o4b2o301b$43b2o7bo8bo79b4o5b2o30b5o274b$44bo5b2o122b2o6bo 123 | 4bo273b$38b2o5b2ob3o15bo107bobo5bo56bo221b$37b2ob2o24bobo92bo12bo8bo3b 124 | o42b6obo3bo219b$38b4o24b2o77b2o13bo2bo21bo32b2o10bo5bo3b3o218b$39b2o 125 | 102b2ob2o11bo3bo53b2ob2o8bo5bo5bo218b$55b4o84bo2bo12bo3bo5b2o47b4o9bo 126 | 3bo3b2obo218b$55bo3bo83bo2bo12bo3bo5bobo47b2o12bo5b3o219b$55bo88b2o9b 127 | 2o3bobo6bo62b2o227b$56bo98b2o4bo69b4o226b$58b2o170b2ob2o226b$142bo2bo 128 | 85b2o228b$55b2o3b2obo77bo319b$54b2ob3ob3o77bo3bo315b$55b7o79b4o13b4o 129 | 51b2o246b$56b4o98bo3bo49b2ob2o8bo235b$70b4o84bo54b4o3bo4bobo233b$70bo 130 | 3bo84bo2bo51b2o3bo5bo2bo232b$70bo8b6o133bo2bo6bo232b$71bo2bo4bo5bo128b 131 | 2o3bo5bo2bo8bo223b$79bo133b4o3bo4bobo9b2o222b$80bo4bo126b2ob2o8bo235b$ 132 | 82b2o113b4o5b2o5b2o26bo219b$197bo3bo3b2ob2o22b3o4bo3bo217b$197bo8b4o 133 | 22bo5bo222b$198bo2bo5b2o24bo4bo4bo217b$238b5o218b$210bo250b$200b2o8b2o 134 | 15b3o231b$199bo2bo9bo14bo233b$199bo2bo4b5o16bo232b$199b2ob2o3b4o250b$ 135 | 201b2o4bo253b$222b3o236b$222bo238b$223bo237b$197b4o260b$197bo3bo13bo2b 136 | o6b2o234b$197bo16bo8bo237b$198bo2bo12bo3bo3bo6b2o3b2o225b$214b4o4bo7bo 137 | 2bo227b$222b12ob2o224b$227b2o2b2ob3o224b$232bobo226b$233bo227b$223b2o 138 | 236b$222b2ob2o234b$223b4o234b$224b2o43b3o189b$206b2o61bo191b$205b4o61b 139 | o190b$204b2ob2o252b$205b2o5b2ob3o243b$211bo5b2o242b$210b2o7bo241b$211b 140 | o5b2o242b$205b2o5b2ob3o9b2o232b$190bo2bo5b2o3b2ob2o18bobo231b$189bo8b 141 | 4o3b4o18bo233b$189bo3bo3b2ob2o4b2o253b$189b4o5b2o30b5o226b$222b2o6bo4b 142 | o225b$222bobo5bo230b$209bo12bo8bo3bo225b$193b2o13bo2bo21bo227b$191b2ob 143 | 2o11bo3bo249b$191bo2bo12bo3bo5b2o242b$191bo2bo12bo3bo5bobo241b$192b2o 144 | 9b2o3bobo6bo243b$203b2o4bo24bo226b$225b6obo3bo224b$190bo2bo31bo5bo3b3o 145 | 223b$189bo35bo5bo5bo223b$189bo3bo32bo3bo3b2obo223b$189b4o13b4o18bo5b3o 146 | 224b$206bo3bo16b2o232b$206bo19b4o231b$207bo2bo14b2ob2o231b$226b2o11b3o 147 | 219b$239bo221b$240bo220b$208b2o251b$207b2ob2o8bo240b$208b4o3bo4bobo 148 | 238b$209b2o3bo5bo2bo237b$213bo2bo6bo237b$209b2o3bo5bo2bo237b$208b4o3bo 149 | 4bobo238b$207b2ob2o8bo8b3o229b$192b4o5b2o5b2o19bo6bo224b$192bo3bo3b2ob 150 | 2o25bo3bo3bo222b$192bo8b4o28bo227b$193bo2bo5b2o29bo4bo222b$224b3o6b5o 151 | 223b$224bo236b$195b2o7bo20bo235b$194bobo3b2o7b5o247b$194bo18bo247b$ 152 | 194b3o13b3o6b3o239b$205b2o4bo7bo241b$205b2o13bo240b3$192b4o265b$192bo 153 | 3bo13bo2bo247b$192bo16bo251b$193bo2bo12bo3bo247b$209b4o! -------------------------------------------------------------------------------- /doc/Midtvejsrapport.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | \usepackage[a4paper, hmargin={2.8cm, 2.8cm}, vmargin={2.5cm, 2.5cm}]{geometry} 3 | \usepackage{eso-pic} % \AddToShipoutPicture 4 | \usepackage{graphicx} % \includegraphics 5 | \usepackage{listings} 6 | \usepackage{setspace} 7 | \usepackage{cite} 8 | \usepackage{stmaryrd} 9 | \usepackage{fixltx2e} 10 | \usepackage{amsmath} 11 | \usepackage{tabu} 12 | 13 | \lstset{ 14 | mathescape, 15 | moredelim=[is][\underbar]{_}{_} 16 | } 17 | 18 | \definecolor{Background}{rgb}{0.98,0.98,0.98} 19 | \lstset{ 20 | numbers=left, 21 | numberstyle=\footnotesize, 22 | numbersep=1em, 23 | xleftmargin=1em, 24 | framextopmargin=2em, 25 | framexbottommargin=2em, 26 | showspaces=false, 27 | showtabs=false, 28 | showstringspaces=false, 29 | frame=l, 30 | tabsize=4, 31 | % Basic 32 | basicstyle=\ttfamily\small\setstretch{1}, 33 | backgroundcolor=\color{Background} 34 | } 35 | 36 | \author{ 37 | \Large{Anna Sofie Kiehn and Henriks Urms}\\ 38 | \\ \textit{Supervisor:} Martin Elsman 39 | % \texttt{a.kiehn89@gmail.com} \\ 40 | %\\ \texttt{a.kiehn89@gmail.com} \\ \\ 41 | %\Large{Henriks Urms} 42 | %\\ \texttt{urmshenrik@gmail.com} 43 | } 44 | 45 | \title{ 46 | \vspace{5cm} 47 | \Huge{Midvejsrapport} \\ 48 | \Large{Compiling TAIL to Futhark} 49 | } 50 | 51 | \begin{document} 52 | %\renewcommand{\arraystretch}{1.2} 53 | 54 | \newcommand{\evals}[1]{\llbracket #1 \rrbracket} 55 | 56 | %% Change `ku-farve` to `nat-farve` to use SCIENCE's old colors or 57 | %% `natbio-farve` to use SCIENCE's new colors and logo. 58 | \AddToShipoutPicture*{\put(0,0){\includegraphics*[viewport=0 0 700 600]{include/natbio-farve}}} 59 | \AddToShipoutPicture*{\put(0,602){\includegraphics*[viewport=0 600 700 1600]{include/natbio-farve}}} 60 | 61 | %% Change `ku-en` to `nat-en` to use the `Faculty of Science` header 62 | \AddToShipoutPicture*{\put(0,0){\includegraphics*{include/nat-en}}} 63 | 64 | \clearpage\maketitle 65 | \thispagestyle{empty} 66 | 67 | \newpage 68 | 69 | \abstract 70 | 71 | \newpage 72 | 73 | \tableofcontents 74 | 75 | \newpage 76 | 77 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 78 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 79 | %%%%%%%%%%% REPORT STARTS HERE %%%%%%%%%%%%%%%%%%%% 80 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 81 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 82 | \section{Prelude} 83 | 84 | In the prelude part of this paper we try to meet the requirements of the "midtvejsrapport" assignment. 85 | After the prelude section this rapport contains draft versions of the final report. Some of these sections are further 86 | along than other so please keep in mind that the sections are draft and not a finished product. 87 | Some of the sections only contain a short description of what we expect the final sections should contain, however we still have 88 | the section in place to get an idea of the structure of the final report. 89 | 90 | \subsection{Problem Definition} 91 | Is it possible, effectively to compile TAIL programs, produced by the APL compiler AplTail, 92 | into Futhark programs and thereby make use of the Futhark infrastructure for optimization 93 | and the possibility for targeting parallel hardware? 94 | 95 | \subsection{Problem clarification} 96 | The language APL is a mature array programming language that gives rise to parallelism. 97 | The AplTail compiler produces a typed intermediate language TAIL from APL source code \cite{ElsmanDybdal:Array:2014}. 98 | The purpose of the Futhark language is to make it possible for the programmer to express parallelism in a high level language 99 | while at the same time targeting parallel architectures \cite{TroelsHenriksen}. 100 | We wish to assess the possibility of compiling TAIL to Futhark thereby making it possible to execute APL in parallel 101 | by using the Futhark language as backend. 102 | This also allows us to take advantage of the various optimizations that Futhark provides, most notably fusion \cite{TroelsHenriksen}. 103 | 104 | The challenges of mapping TAIL to Futhark lie mainly in the differences between how the two languages express parallelism. 105 | The TAIL the parallelism is always flat, even for multi-dimensional arrays where as Futhark permits nested parallelism but always 106 | does so at the level of arrays\cite{ElsmanDybdal:Array:2014} \cite{TroelsHenriksen}. 107 | 108 | We will not test the produced code on parallel hardware as no parallel backend for Futhark yet exists. 109 | 110 | \subsection{Methods and tools} 111 | In this section we will describe the methods and tools used to create the compilation scheme and implementation of the compiler. 112 | 113 | \subsubsection{Symbolic notation to describe the compilation scheme} 114 | We are going to use a symbolic notation to illustrate a compilation scheme showing the compilation in a way 115 | that abstracts away implementation details \cite{MartinElsmanNotation}. 116 | We use this tool to create a description of the compilation scheme that is independent of the implementation and 117 | which should make it possible to implement the compiler in any language. 118 | 119 | \subsubsection{Parser} 120 | We used a parser that was created during an earlier project \cite{APLACC} instead of creating our own. 121 | This was done in order to use already existing tools and save our resources for work that had not already been done by others. 122 | We did however have to update the parser a little as it was a few months old and therefore did not support the 123 | newest additions to the TAIL language. 124 | Details about this implementation can be found in the section \textit{Implementation of the compiler}. 125 | 126 | \subsubsection{Language used} 127 | The implementation of the compiler is written in the programming language Haskell. 128 | We chose to write in Haskell because it is a functional language that is suitable for creating a compiler because of the 129 | pattern matching feature and the ease with which one can recursively go through the thee structure that 130 | represents the program code. Haskell has more features and libraries than Standard ML and that is why it was chosen. 131 | 132 | \subsubsection{Libraries used} 133 | 134 | In our implementation we have used various external libraries, we will discuss some of the non-standard used libraries here. 135 | For building our project and managing external libraries we have used the cabal package \cite{cabal}. This is a very common thing to 136 | do in Haskell projects and should make it easy for anyone to build our code. 137 | We use the tasty package \cite{tasty} which provides a test framework that we use to implement our tests. Furthermore we have used the 138 | package tasty-golden \cite{tasty-golden} which is a plug-in for the tasty framework that allows to test against "golden" files. 139 | A lot of projects implement their own test frameworks and we could have done the same. 140 | We chose not to do so as this freed us to use our resources on developing the compiler instead of developing and maintaining a 141 | test framework which could prove time consuming. 142 | Finally the existing parser for TAIL makes use of the popular parsec library \cite{parsec} and we have continued to use 143 | parsec in our continuation of the parser. 144 | 145 | \subsubsection{Testing} 146 | 147 | We provide a test suite for testing of our compiler. 148 | Each test compiles an TAIL program and tries to run it in the Futhark interpreter and the matches the result against a reference 149 | value found in a file with the extension ok. 150 | This testing procedure makes sure that our compiler produces valid Futhark code from our test programs. 151 | Most of the tests are generated from APL code with the AplTail compiler. 152 | 153 | We also plan to provide benchmarks that test the speed of our code in the future. 154 | 155 | \subsection{Project status} 156 | The project is coming along as planned and we are on schedule which can be seen in Figure \ref{fig:gantt}. 157 | It took less time than expected to adapt the parser to work with the latest version of TAIL 158 | which meant that we started on the implementation of the TAIL functions in the compiler a few days before scheduled. 159 | We are done with implementing half of the functions in TAIL to Futhark source code. 160 | As we are working on testing the implementation while we develop we are halfway through testing the functionality as well. 161 | 162 | \begin{figure}%[width=\textwidth]%[p] 163 | \centering 164 | \includegraphics[width=\textwidth]{midvejsgantt3.png} 165 | \caption{Gantt chart of the project activities. The remaining time of the project is highlighted by a red box.} 166 | \label{fig:gantt} 167 | \end{figure} 168 | 169 | The compilation scheme we are going to create are still being developed. 170 | The symbolic notation is something we will work intensively on from now on. 171 | So far only a small portion of the compilation has been written in a symbolic notation, 172 | the rest is still described in a more informal text form. 173 | We will use the remaining time in the project focus on getting the last functions implemented and tested. 174 | 175 | We will also test the efficiency of our generated Futhark code using benchmarks to compare it to the C-code generated by the TAIL compiler. 176 | 177 | 178 | \newpage 179 | 180 | \section{Introduction} 181 | 182 | In recent years, there has been a lot of focus on leveraging the power of parallel hardware. 183 | One approach has been to design programming languages with explicit data-parallel constructs that can be compiled 184 | into highly parallel code. One such language is Futhark. The aim of Futhark is to target parallel hardware such as 185 | GPUs while itself being the target of more programmer-productivity oriented languages. The Futhark compiler 186 | performs several optimizations, such as fusion, which enhance the degree of 187 | parallelism \cite{T.Henriksen&C.Oancea}.\\ 188 | 189 | APL is an array language and includes various operations that are central to the language and are good candidates 190 | for parallel execution. Efforts in compiling APL to parallel backends already exist in the form of the language 191 | TAIL (Typed array intermediate language) and it’s compiler \cite{ElsmanDybdal:Array:2014}. 192 | The TAIL compiler captures the parallelism inherent in APL source code and brings it to a much more manageable form. 193 | In our work we provide a compiler from TAIL 194 | to Futhark thus bridging the gap between APL and Futhark.\\ 195 | 196 | The language Futhark is designed to target parallel architectures and at the same time acting 197 | as an intermediate language for more feature-rich languages. By compiling APL to Futhark through TAIL the 198 | Futhark compiler can be used to generate parallel code from APL once a parallel backend for 199 | Futhark is completed.\\ 200 | 201 | There are traditionally five stages of a compiler if you compile a high level language to machine code: 202 | lexical analysis, syntax analysis, type checking, intermediate code generation, register allocation, machine 203 | code generation and assembly and linking \cite{TorbenMogensen}. However, in this project we are compiling from 204 | one high level language to another high level language. The structure does therefore look a little different. 205 | The first two phases are still lexical analysis and syntax analysis and are handled by a parser. 206 | We made use of an already existing parser \cite{APLACC} and only modified it in order for it to work on the latest 207 | version of TAIL. The third phase is transforming the abstract syntax tree of TAIL to the abstract syntax tree 208 | representing the code in Futhark and the fourth phase is printing the AST so it becomes correct 209 | Futhark source code. \\ 210 | 211 | One of the main point of interest in the compilation between TAIL and Futhark is compiling the four array operators 212 | of TAIL: {\tt each}, {\tt eachV}, 213 | {\tt reduce} and {\tt zipWith} to Futhark source code that include the four second-order array combinators in Futhark: 214 | {\tt map}, {\tt filter}, {\tt reduce} and {\tt scan} \cite{ElsmanDybdal:Array:2014}\cite{TroelsHenriksen}. 215 | However as the functionality of these functions are not completely 216 | identical the work lies in creating a mapping that retains the parallelism in the original code in the target language.\\ 217 | This can be seen in the example below which illustrate this difference. The reduce function in the 218 | TAIL language is mapped to a nested reduce function in the Futhark language. 219 | As some function names exists in both languages the Futhark version of such occurrences are \underline{underlined}. 220 | 221 | \begin{lstlisting}[numbers=none,frame=none] 222 | reduce(+, [[1,2,3,4],[5,6,7,8]])) 223 | 224 | => 225 | 226 | _reduce_(fn x => map(+,x),[[1,2,3,4],[5,6,7,8,]]) 227 | 228 | \end{lstlisting} 229 | 230 | This paper contributes with a compilation scheme that are implementation independent, showing a replicable 231 | way of how to translate the typed intermediate language of APL, TAIL, to the functional language Futhark. Also 232 | this paper presents an implementation of the previous mentioned scheme in Haskell. The efficiency of this 233 | implementation have been tested by comparing benchmarks test on code generated by the C-backend to TAIL 234 | and the generated Futhark source code by using the C-backend to Futhark. \\ 235 | 236 | The project is open source and the source code can be found here:\\ https://github.com/henrikurms/tail2futhark. 237 | 238 | \section{TAIL} 239 | 240 | TAIL is a typed array intermediate language and the target of an APL compiler. 241 | APL is an older language created in the 1960's by Kenneth E. Iverson. 242 | APL is an array programming language, its main type is the multi-dimensional array 243 | and most of the built-in functions in the language are array operators that work on this type. 244 | All of its built-in functions or operators are represented by unicode symbols allowing for very concise code. 245 | The APL language is dynamically typed. It supports first and second order functions and it supports polymorphism in 246 | both its first and second order functions and operators. 247 | Even though it is not a new language it is still used in the financial world 248 | where large code bases are still operational and actively developed \cite{ElsmanDybdal:Array:2014}. \\ 249 | 250 | % TAIL does not support curried functions. 251 | 252 | TAIL was designed with the purpose of targeting parallel architectures, though no parallel backend for TAIL yet exists. 253 | Another backend to TAIL exists however which compile TAIL efficiently into a C-like language. TAIL does not support 254 | all APLs operators but only a subset of these \cite{ElsmanDybdal:Array:2014}.\\ 255 | 256 | A TAIL programs always consist of a single expression. An expression can then be a value, variable, 257 | list of expressions, a let expression or an operator. \\ 258 | 259 | TAILs type system takes the parallelism of APL and transforms it to a more manageable form adding explicit type 260 | information to the constructs. 261 | Another benefit of the expressivity of TAILs type system is that it allows the (TAIL) compiler to express some operators which 262 | are primitive in APL using simpler operators, one such operator is that of the inner product \cite{ElsmanDybdal:Array:2014}. \\ 263 | 264 | Most of the operators in TAIL are polymorphic in respect to array ranks and base types. 265 | Some of them only take some polymorphic arguments but also take specific type arguments. 266 | An example is the {\tt take} function. It takes as argument a number (of type int) and an array of type $\alpha$.\\ 267 | 268 | The central type in TAIL is, like in APL, the multi-dimensional array type. 269 | Array types consist of a base type and a rank. 270 | The base type of an array is the type of the elements in the array and can currently be of the 271 | type: {\tt int}, {\tt double}, {\tt bool} {\tt char}. 272 | Scalars are a special case of the array type and is represented as an array of rank 0. 273 | Vectors can be represented in two different ways in TAIL. 274 | Either as an array of rank 1 or as the special vector type. 275 | The special vector type is used for vector literals where the length of the vector is known at compile time \cite{ElsmanDybdal:Array:2014}. \\ 276 | 277 | 278 | There are four parallel operators in TAIL, {\tt each}, {\tt eachV}, {\tt reduce} and {\tt zipWith}. 279 | The functions {\tt each} and {\tt eachV} are known in many languages as map. 280 | The function takes two arguments: a function and an array and then apply this function on the array. 281 | If the rank of the array is greater than 1 the {\tt each} function work as a map on the fattened representation of the array, 282 | that is, the function is applied on the inner most dimension of the array. 283 | The {\tt eachV} function is a special case of {\tt each} and is used on the special vector type.\\ 284 | 285 | The function {\tt reduce} works similar to fold known in functional languages. 286 | Their function takes as arguments a associative binary operator, a neutral element and array. 287 | The {\tt reduce} function the uses the binary operator 288 | to reduce an array of rank $\gamma+1$ to an array of rank $\gamma$ by reducing along the inner-most dimension. 289 | The difference to fold is that the operator has to be associative and the start element has to be neutral 290 | because the execution is parallel. 291 | 292 | The {\tt zipWith} function takes as arguments a function and two arrays. 293 | It then applies the function on the pair of elements consisting of the i'th element 294 | from the first array and the i'th element from the second array. 295 | Like the other tree operators it works on the inner-most dimension of the array\cite{ElsmanDybdal:Array:2014}\cite{TorbenMogensen}. \\ 296 | 297 | %%If we do not show the type schemes here we should reference to where they can be found in the article!!!!!!!!!! 298 | 299 | %The types in TAIL are divided into four types. Firstly there are base types consisting of {\tt int}, {\tt double}, {\tt bool} and the polymorphic type {\tt $\alpha$} that can represent any one of them. Secondly, there are shape types that can be either a scalar value/variable of type int, or a shape variable or a combination of two shape variables. \\ 300 | %Then there is array types that consist of a base type and a rank. Finally there is 301 | 302 | 303 | %The main datatype in TAIL is also a multidimensional array. Array types are in TAIL annotated with their ranks explicitly. 304 | %TAILs type system treats scalar values as special cases of the array time namely an array with rank 0. 305 | 306 | %There are two separate representations of vectors, either the special vector type used when the length of the vector is known or the general array type where the rank is 1. 307 | 308 | %Besides array and vector types, TAIL also have base types in the form of {\tt int}, {\tt double}, {\tt bool} and {\tt $\alpha$}. 309 | 310 | %So far TAIL only support a subset of the APL functions and operators. 311 | 312 | \section{Futhark} 313 | 314 | Futhark is a functional programming language inspired by Haskell and Standard ML. 315 | It was designed to be an attractive choice for expressing complex programs by having enough expressive power without 316 | losing the possibility to do aggressive optimization and creating parallelism even though the higher the expressive power of the 317 | language the more difficult optimization often become. 318 | Due to the focus on optimization the Futhark language only supports regular arrays 319 | (arrays where all inner dimensions are of the same length) 320 | because of the complication to size analysis supporting non-regular arrays would create. 321 | However Futhark do support nested parallelism as this is a feature many programs 322 | depend upon even though this feature does make optimization more difficult \cite{TroelsHenriksen}. 323 | 324 | %%something more about specific optimization????????????????\\ 325 | 326 | 327 | A Futhark program consist of a list of function declarations of the form: 328 | \begin{lstlisting}[numbers=none,frame=none] 329 | fun return-type name(params...) = body 330 | \end{lstlisting} 331 | 332 | The body of the Futhark function then consist of an expression.\\ 333 | 334 | The Futhark language support anonymous functions, but it is not possible to curry functions in the Futhark language, 335 | so the anonymous function can only take one argument. 336 | If the function needs more than one argument it needs to be given as a tuple. 337 | Except for inline anonymous functions all functions are defined globally \cite{TroelsHenriksen}. \\ 338 | 339 | The Futhark language supports multidimensional arrays in the form of nesting of array types, 340 | i.e. an int array array will contain int arrays and so on. 341 | The Futhark language has four base types: {\tt int}, {\tt real}, {\tt char} and {\tt bool}. 342 | In general the Futhark language does not support polymorphism in functions, 343 | the only exception is the built-in second-order array combinators that work on arrays of any base type. \\ 344 | 345 | Futhark is mostly a first order language but supports bulk (parallel) operations on arrays 346 | using the built-in second-order array combinators (SOACs) of the language. 347 | The SOACs consist of {\tt map}, {\tt filter}, {\tt reduce} and {\tt scan}. 348 | The operators have the expected functionality also found in Haskell and Standard ML, 349 | that is {\tt map} takes a function and an array and apply the function on the array. 350 | If the array is multi-dimensional the function is applied to the outer most dimension. 351 | The function {\tt reduce} takes as arguments a function, a neutral element and an array. 352 | Like the {\tt map} function, the {\tt reduce} function takes the function it is given in the arguments 353 | and apply it on the outer-most dimension of the array \cite{TroelsHenriksen}. \\ 354 | 355 | %The basic types in Futhark is {\tt int}, {\tt char}, {\tt bool}, {\tt real} and regular arrays. 356 | %The type system of Futhark does not support polymorphism, 357 | %however the build-in SOACs work on all regular arrays created of the basic types. 358 | 359 | %Does not support polymorfism in types 360 | 361 | \section{The differences between TAIL and Futhark} 362 | In this section we are going to flesh out the concrete differences between the two languages. 363 | 364 | The differences in how Futhark and TAIL handles parallelism is tightly connected with the differences in their type systems. 365 | Multi-dimensional arrays in TAIL are typed by a base type and a rank. The array operators of TAIL are polymorphic in the rank 366 | of the array. This means that the operators that the array operators take as arguments always work on base types \cite{ElsmanDybdal:Array:2014}. In contrast 367 | arrays in Futhark can be of any type, even other arrays. Arrays of arrays are how multi-dimensional arrays are represented in Futhark. 368 | This means that the SOACs in Futhark can apply the functions they take as arguments to arrays themselves, these functions can then 369 | map other functions and so on, this leads to nested parallelism \cite{TroelsHenriksen}. 370 | %\subsection{Polymorphism} 371 | 372 | \section{Compilation strategy} 373 | In this section we are going to introduce our compilation scheme and explain the problems in compiling the different functions 374 | having a special focus on the more interesting cases. 375 | We will also explain our reasoning behind the chosen compilation and what alternatives there are. 376 | 377 | Below we introduce a scheme of the compilation from TAIL to Futhark. The scheme uses a mathematical notation to illustrate 378 | the compilation of the TAIL expressions to Futhark code/expressions? 379 | 380 | 381 | This scheme works as an abstract model of the transformation and is implementation independent. It is based on similar schemes \cite{MartinElsmanNotation} . \\ 382 | 383 | The TAIL language consist of the following expressions \cite{ElsmanDybdal:Array:2014}: 384 | 385 | \begin{lstlisting}[numbers=none,frame=none] 386 | e$_T$ ::= x | i | d | c | inf | -e | let x:t = e$_1$ in e$_2$ | 387 | op[e$_1$,...,e$_n$] | fn x:t e | [e$_1$,...,e$_n$] 388 | 389 | \end{lstlisting} 390 | 391 | The Futhark language consist of the following expressions\cite{TroelsHenriksen}: 392 | \begin{lstlisting}[numbers=none,frame=none] 393 | e$_F$ ::= 394 | 395 | \end{lstlisting} 396 | 397 | The compilation between these two languages can be seen below: \\ 398 | 399 | 400 | %%% Table 401 | \begin{tabular}{l c l}% to \linewidth {l c X} 402 | $\evals{x}$ & $=$ & $x$ \\ 403 | $\evals{i}$ & $=$ & $i$ \\ 404 | $\evals{d}$ & $=$ & $d$ \\ 405 | $\evals{c}$ & $=$ & $c$ \\ 406 | $\evals{-e}$ & $=$ & -$\evals{e}$ \\ 407 | $\evals{ \text{let } x:t = e_1 \text{ in } e_2} $ & $=$ & let $\evals{x} = \evals{e_1} \text{ in } \evals{e_2} $\\ 408 | $\evals{[e_1,...,e_n]}$ & $=$ & $ [ \evals{e_1},...,\evals{e_n}]$\\ 409 | $\evals{\text{op } [e_1,...,e_n]}$ & $=$ & $\evals{\text{op}}_{op} \evals{[e_1,...,e_n]}$\\ 410 | 411 | $\evals{\text{op} [e_1,...,e_n]}$ & $=$ & $\evals{\text{op}}_{fun} \; (\evals{e_1},...,\evals{e_n})$\\ 412 | $\evals{\text{op} [e_1,e_2]}$ & $=$ & $\evals{e_1} \; \evals{\text{op}}_{op} \; \evals{e_2}$\\ 413 | 414 | $\evals{\text{each}_{[t_1,t_2,r]}(f,a)}$ & $=$ & $ 415 | \begin{cases} 416 | $map$(\evals{f}_{fn}^{\evals{t_2}},\evals{a}) & r=1\\ 417 | $map (fn $t_2^r \; (t_1^r \; x)$ {\tt =>} $ \evals{\text{each}_{[t,r-1]}(f,x)},\evals{a}) & r > 1 \\ 418 | \end{cases}$\\ 419 | 420 | $\evals{\text{eachV}_{[t_1,t_2,r]}(f,a)}$ & $=$ & map$(\evals{f}_{fn}^{\evals{t_2}},\evals{a}) $ \\ 421 | 422 | $\evals{\text{vrotate}_{[t,r]}(i,a)}$ & $=$ & map(fn x {\tt =>} a[x + i {\tt \%} \text{size}(0,a)], iota(size(0,a)) \space\space , x = fresh\\ 423 | $\evals{\text{vreverse}_{[t,r]}(a)}$ & $=$ & map(fn x {\tt =>} a[\text{size}(0,a)-x-1], $\text{iota}(\text{size}(0,a))$ \space\space , x = fresh\\ 424 | $\evals{\text{reshape}_{[t,r_1,r]}(a_1,a_2)}$ & $=$ & reshape$(\evals{a_1},(\text{reshape1}_{\evals{t}}( 425 | % \prod_{i=0}^{r_1} \text{size}(i,a_1) 426 | \text{osize}%(\text{size}(0,a_1)*\ldots*\text{size}(r_1,a_1) 427 | , \text{reshape}( 428 | \text{isize}%\text{size}(0,a_2)*\ldots*\text{size}(r_2,a_2) 429 | , \evals{a_2})))) $ \\ 430 | && \hspace{4ex} where osize = $\text{size}(0,a_1)*\ldots*\text{size}(r_1,a_1)$ \\ 431 | && \hspace{4ex} \phantom{where} isize = $ \text{size}(0,a_2)*\ldots*\text{size}(r_2,a_2) $ \\ 432 | 433 | $\evals{\text{reduce}_{[t,r]}(f,n,a)}$ & $=$ & $ 434 | \begin{cases} 435 | \text{reduce}(\evals{f}_{fn}^{\evals{t}},\evals{n},\evals{a}) & r=1 \\ 436 | $map (fn $ t^{r-1} \; (t^r \; x)$ {\tt =>} $ \evals{\text{reduce}_{[t,r-1]}(f,n,x)},\evals{a}) & r>1\\ 437 | \end{cases}$\\ 438 | 439 | $\evals{\text{zipWith}_{[t_1,t_2,t_3,r]}(f,a_1,a_2)}$ & $=$ & \\ 440 | \multicolumn{3}{r}{ $\begin{cases} 441 | $map$(\evals{f}_{fn}^{\evals{t_3}},$zip($\evals{a_1},\evals{a_2})) & r=1 \\ 442 | $map(fn $t_3^{r-1} \; (t_1^{r-1} \; x, t_2^{r-1} \; y) $ {\tt =>} $ 443 | \evals{\text{zipWith}_{[t_1,t_2,t_3r-1]}(f,x,y)} , $zip($ \evals{a_1}, \evals{a_2})) & r>1\\ 444 | \end{cases}$ }\\ 445 | 446 | $\evals{\text{cat}_{[t,r]}(a_1,a_2)}$ & $=$ & $ 447 | \begin{cases} 448 | \text{concat}(\evals{a_1},\evals{a_2}) & r=1 \\ 449 | $map (fn $ \evals{t}^{r-1} \; (\evals{t} \; x, \evals{t} \; y)$ {\tt =>} $ \evals{\text{cat}_{[t,r-1]}(x,y)}, \text{zip}(\evals{a_1}, \evals{a_2}) & r>1\\ 450 | \end{cases}$\\ 451 | 452 | $\evals{\text{first}_{[t,r]}(a)}$ & $=$ & let x = $\evals{a}$ in $x[\underbrace{0,...,0}_\text{r times}]$\\ 453 | 454 | $\evals{\text{firstV}_{[t,r]}(a)}$ & $=$ & $\evals{\text{first}_{t,1}(a)}$\\ 455 | 456 | $\evals{\text{take}(i,a)}$ & $=$ & reshape(oshape,\text{take1}$_{\evals{t}}$(osize,\text{reshape}(isize,$\evals{a})))$\\ 457 | && \hspace{4ex} where oshape = ($|i|, \text{size}(1,\evals{a}),\cdots,$size(r,$\evals{a}$))\\ 458 | && \hspace{4ex} \phantom{where} osize = ($i* \text{size}(1,\evals{a}) *\ldots*$size(r,$\evals{a}$))\\ 459 | && \hspace{4ex} \phantom{where} isize = \text{size}(0,$\evals{a}$)$*\ldots*$\text{size}(r,$\evals{a}$)\\ 460 | 461 | $\evals{\text{takeV}_t(d,a)}$ & $=$ & $\text{take1}_{\evals{t}}(\evals{d},\evals{a})$\\ 462 | 463 | $\evals{\text{drop}(i,a)}$ & $=$ & \text{reshape}(\text{oshape}, $\text{drop1}_{\evals{t}}(\text{osize}, \text{reshape}(\text{isize},\evals{a}))$\\ 464 | && \hspace{4ex} where oshape = (max(0,size(0,$\evals{a}$)-$|i|$),size(1,$\evals{a}$)$,\ldots,$size(r,$\evals{a}$))\\ 465 | && \hspace{4ex} \phantom{where} osize = ($i *$size(1,$\evals{a}$)$ * \ldots*$size(r, $\evals{a}$))\\ 466 | && \hspace{4ex} \phantom{where} isize = \text{size}(0,$\evals{a}$)$*\ldots*$\text{size}(r,$\evals{a}$)\\ 467 | 468 | $\evals{\text{dropV}_t(d,a)}$ & $=$ & $\text{drop1}_{\evals{t}}(\evals{d},\evals{a})$\\ 469 | 470 | $\evals{\text{transp}_{t,r}(a)}$ & $=$ & rearrange$((r-1,...,0),\evals{a})$\\ 471 | 472 | $\evals{\text{transp2}_{t,r}(a_1,a_2)}$ & $=$ & let $x$ = $\evals{a_1}$ in rearrange(($x[0]$-$1,\ldots,x[r$-$1]$-$1$),$\evals{a_2})$\\ 473 | 474 | %$\evals{\text{cons}_[t,r](e,a)}$ & $=$ & 475 | % $\begin{cases} 476 | % \text{concat}([\evals{e}],\evals{a}) & r= 1\\ 477 | % \text{map (fn }$$(x,y) $ {\tt =>} $ \evals{\text{cons}_{[t,r]}(x,y)}, \text{ zip}(\evals{e},\evals{a}))$$ & r > 1 478 | % \end{cases}$\\ 479 | 480 | $\evals{\text{cons}_[t,r](e,a)}$ & $=$ & rearrange$((r,\ldots,0), \text{concat(exp,arr)})$\\ 481 | && \hspace{4ex} where exp = rearrange((r-1,\ldots,0),$\evals{e}$)\\ 482 | && \hspace{4ex} \phantom{where} arr = rearrange((r-1,\ldots,0),$\evals{a}$)\\ 483 | 484 | $\evals{\text{snoc}_[t,r](a,e)}$ & $=$ & rearrange$((r,\ldots,0), \text{concat(arr,exp)})$\\ 485 | && \hspace{4ex} where exp = rearrange((r-1,\ldots,0),$\evals{e}$)\\ 486 | && \hspace{4ex} \phantom{where} arr = rearrange((r-1,\ldots,0),$\evals{a}$)\\ 487 | 488 | %$\evals{\text{snoc}_[t,r](a,e)}$ & $=$ & 489 | % $\begin{cases} 490 | % \text{concat}([\evals{a}],\evals{e}) & r= 1\\ 491 | % \text{map (fn }$$(x,y) $ {\tt =>} $ \evals{\text{snoc}_{[t,r]}(x,y)}, \text{ zip}(\evals{a},\evals{e}))$$ & r > 1 492 | % \end{cases}$\\ 493 | 494 | $\evals{\text{iota}(a)}$ & $=$ & map$(+ \; (1), \text{iota}(\evals{a})$\\ 495 | 496 | $\evals{\text{iotaV}(a)}$ & $=$ & $\evals{\text{iota}(a)}$\\ 497 | 498 | $\evals{\text{shape}_{t,r}(a)}$ & $=$ & $[\text{size}(0,\evals{a}),...,\text{size}(r-1,\evals{a})]$\\ 499 | 500 | $\evals{\text{shapeV}_{t,r}(a)}$ & $=$ & $[r]$\\ 501 | gi 502 | \\ 503 | %\end{tabular}\\ 504 | % 505 | %The compilation of fn are descirbed in a table of its own\\ 506 | % 507 | %\begin{tabular}{l c l} 508 | $\evals{ \text{fn } x:t $ {\tt =>} $ e}^{\tau}_{fn} $ & $=$ & $ \text{fn } \tau (\evals{t}\; x) $ {\tt =>} $ \evals{e}$\\ 509 | $\evals{ \text{fn } x:t_1$ {\tt =>} $\text{fn } y:t_2 $ {\tt =>} $ e}^{\tau}_{fn} $ & $=$ & $ \text{fn } \tau (\evals{t_1}\; x, \evals{t_2} \; y) $ {\tt =>} $ \evals{e}$\\ 510 | \end{tabular}\\ 511 | 512 | The gereral compilation of operators:\\ 513 | 514 | \begin{tabular}{l c l} 515 | $\evals{addi}_{op}$ & $=$ & $+$\\ 516 | $\evals{i2d}_{fun}$ & $=$ & toReal\\ 517 | \end{tabular}\\ 518 | 519 | \paragraph{reshape} 520 | reshape gets as argument the return type.\\ 521 | It is not possible to reshape something that has length 0. It is possible in aplt but we do not support it in our implementation. \\ 522 | 523 | \paragraph{cons} takes an array of rank $\gamma$ and an array of rank $\gamma+1$ and concatinates the elements of the 524 | array of rank $\gamma$ in the front of the elements of the array of rank $\gamma +1$. This result in an array of rank $\gamma+1$. 525 | The idea behind the compilation of the function snoc was to transpose the two arrays, then concating the arrays and then transposing the resulting array again. That way we would get the desired result of the nth elements from the first array added to the nth element of the second array. However the Futhark transpose function differs slightly from the wished functionality in that. ...\\ 526 | 527 | As mentioned previously a Tail program always consists of a single expression, 528 | whereas a Futhark program is a list of function declarations. 529 | The Tail expression is therefore translated/compiled to a Futhark expression by making it the body of the Futhark function\cite{ElsmanDybdal:Array:2014}\cite{TroelsHenriksen}. 530 | Thus the focus should be on translating Tail expressions to Futhark expressions. 531 | There are 10 different kind of Tail expressions most of which has exact equivalents in the Futhark language. 532 | This includes but are not limited to, variables, let expressions and literals. 533 | Thus the interesting case is really when the expression to compile is an operator expression. \\ 534 | 535 | These operators consist of the scalar operators: add, addi, subi, subd, multi, multd, mini, mind, maxi, maxd, andb, orb, xorb, nandb, norb, notb, lti, ltd, ltei, lted, gti, gtd, gtei, gted, eqi, eqd, negi, negd, i2d and b2i, and the array operators: iotaV, iota, eachV, each, reduce(V), reduce, shapeV, shape, reshape, reshape0, reverse, vreverse, rotateV, vrotateV, rotate, transp, transp2, takeV, take, dropV, drop, consV, cons, snocV, snoc, firstV, first, zipWith, catV and cat \cite{ElsmanDybdal:Array:2014}. \\ 536 | 537 | Most of the scalar operators have equivalents in the Futhark language and are therefore straight forward to compile. 538 | Some of the Tail array operators also have equivalent or almost equivalent counterparts in the Futhark language 539 | but most have not and are therefore interesting to take a closer look at. 540 | 541 | 542 | \section{The parallel operators} 543 | 544 | \subsection{each} 545 | 546 | The type scheme of the {\tt each} function is $each(f,a) :: \forall\alpha\beta\gamma.(\alpha \to \beta) \to [\alpha]^\gamma \to [\beta]^\gamma$. 547 | 548 | The {\tt each} function in TAIL applies a function to every element in the flat representation of the array. 549 | This is a completely parallel operation more commonly known as map. 550 | The {\tt map} combinator in Futhark has slightly different semantics\cite{ElsmanDybdal:Array:2014}. 551 | Since Futhark views a multidimensional array as nested simple arrays it applies the function to every array element. 552 | That is, it maps the function into the outer-most dimension of the array\cite{TroelsHenriksen}. 553 | 554 | To solve this problem we have nested {\tt map}s to the depth of the array with the required function, 555 | for example, an {\tt each} operation over an array of rank 2 would have two {\tt map}s nested in each other so the kernel is 556 | mapped on each element of basic type. 557 | 558 | For example an each operation on an array of rank 2 will look like: 559 | \begin{lstlisting}[numbers=none,frame=none] 560 | each(f,a) => map(fn x => map (f,x), a) 561 | \end{lstlisting} 562 | 563 | This means the parallel {\tt each} operations in TAIL are compiled to parallel code in the Futhark language. 564 | 565 | \subsection{eachV} 566 | The {\tt eachV } is just a special case of the {\tt each} operator that works on vectors, i.e. flat arrays where the size 567 | is known at compile time. We do not use this extra information so this special case is not important for us. 568 | 569 | \subsection{reduce} 570 | The type of the {\tt reduce} function is $reduce(f,id,a) :: \forall\alpha\gamma.(\alpha \to \alpha \to \alpha) \to \alpha \to [\alpha]^{\gamma+1} \to [\alpha]^\gamma$. 571 | The {\tt reduce} function in TAIL uses an associative binary operator to reduce an array of rank 572 | $\gamma+1$ to an array of rank $\gamma$ by reducing along the inner-most dimension\cite{ElsmanDybdal:Array:2014}. 573 | The Futhark reduce on the other hand reduces each array in the outer array, i.e. it reduces along the outer-most dimension\cite{TroelsHenriksen}. 574 | 575 | We have adopted the same approach as with each by using nested maps to map the reduce on the innermost dimension. 576 | 577 | Fore example reducing an array of rank 2 emits the following code: 578 | 579 | \begin{lstlisting}[numbers=none,frame=none] 580 | reduce(+,a) => map(fn x => _reduce_(+,x), a) 581 | \end{lstlisting} 582 | 583 | \subsection{zipWith} 584 | 585 | The zipWith operator applies a scalar binary operator on pairs of elements from two arrays of the same shape two 586 | produce a third array of the same shape as the input arrays \cite{ElsmanDybdal:Array:2014}. 587 | 588 | To do this in Futhark we use the zip function to convert two arrays to an array of tuples and map the binary operator on that array of tuples \cite{TroelsHenriksen}. 589 | 590 | \section{Other interesting operators} 591 | 592 | Besides the parallel operators there are other operators worth mentioning mostly because of non trivial semantics. 593 | 594 | \subsection{reshape} 595 | 596 | The reshape operator also has quite unique semantics in TAIL, if the dimensions of reshape don't match the dimensions of the array, the 597 | array is either truncated or the elements are repeated until the array is long enough \cite{ElsmanDybdal:Array:2014}. 598 | 599 | Futhark has a reshape function that only works for arrays of the correct dimensions \cite{TroelsHenriksen}. 600 | 601 | Our general strategy for compiling reshape is to first ensure that the array is the correct size and then use the Futhark reshape 602 | function to do the final step. To adjust the size we operate on the flat representation of the array, this is easy to produce also 603 | using Futhark reshape. To adjust the array we first make sure it is long enough by extending it using the function replicate and then 604 | truncate it to the correct length with split. 605 | 606 | To keep the implementation simple we generate code that calls generated library functions written in Futhark which do most of the work. 607 | Nevertheless we inline the flattening and reshaping code so we only need reshape functions written in Futhark 608 | for the one dimensional cases. If we wanted to simply call a function instead we would need a separate library function for each 609 | rank and basic type combination which we needed to call reshape on since Futhark only allows declaration of monomorphic functions \cite{TroelsHenriksen}. 610 | 611 | We have to decide where to put the library functions. 612 | We would like the compiler to always output a valid (runnable) Futhark program given a valid TAIL input program, so we would like to 613 | be able to include the library in the output when we run the compiler. 614 | Furthermore since Futhark has no polymorphism we have to include versions of all types, but we would like to only maintain one version. 615 | Finally since Funthark is eventually expected to feature polymorphism and a module system we would like the solution to not be too 616 | extensive\cite{TroelsHenriksen}. Therefore we have coded the functions in the compiler itself. 617 | 618 | We have used this approach throughout our compiler, e.g. the take operator is implemented similarly. 619 | 620 | \subsection{take} 621 | 622 | The {\tt take} operator in TAIL has very unique semantics, for a positive argument that is less than the size of the array it behaves as one would suspect i.e. it returns the first n elements of the array. 623 | For a negative argument {\tt take} returns the last n elements of the array. 624 | If there are not enough elements in the array, {\tt take} pads with zeros. 625 | 626 | In a similar fashion to the TAIL {\tt reshape} function we have used library functions do most of the work. 627 | We flatten the array, let the library function work on the flat representation and finally reshape it to the desired shape. 628 | This approach has all the benefits mentioned earlier. 629 | 630 | \section{Implementation of the compiler} 631 | 632 | 633 | In this section we will present the Haskell implementation of the compiler and describe how it works. 634 | %We will show code snippets that illustrate interesting parts of the compilation. 635 | 636 | The compiler is made up of three parts, the parser, the compiler and the pretty-printer. Once the input is parsed into an AST the 637 | TAIL expression represented by the AST is passed to the the compileProgram function in the file \\ 638 | {\tt src/Tail2Futhark/Compile.hs}. 639 | This function mainly pattern-matches on the tree and in the case of an operator passes the expression to the compileOpExpression 640 | function. 641 | This function matches on the operator name and most operators have their own separate functions that compile them. 642 | In the process every variable has the prefix "t\_" prepended to make sure that when we make new names they cannot clash 643 | with the old ones as long as they don't start with "t\_". 644 | 645 | %we expect that the terms we get in are well typed and correct. 646 | \subsection{Adaption of the parser} 647 | 648 | The parser that we make use of was created in a precious project \cite{APLACC}. 649 | In the time between that project finished and ours commenced the TAIL language 650 | had been updated with new features and we therefore had to update the parser so that it worked with the latest version of TAIL.\\ 651 | 652 | One of the things that had changed was that booleans was added to the TAIL language. %That meant that it had to be added ..\\ 653 | 654 | Another thing that had changed was that the shape type in the older version of TAIL was replaced with a vector type in the newer version \cite{ElsmanDybdal:Array:2014}.\\ 655 | 656 | \section{Testing} 657 | In this section we will present our testing scheme, why we have chosen to test in that way and the results of the test.\\ 658 | 659 | We have used two methods to test the compiler we have created. 660 | One is unit or integration test where we test the entire pipeline from giving it APL source code to running Futhark source code. 661 | The code is parsed through the APL to TAIL compiler \cite{ElsmanDybdal:Array:2014} 662 | through our compiler (TAIL to Futhark) and then through the Futhark compiler \cite{TroelsHenriksen}. 663 | The result is then compared to the content of a file containing the expected result. 664 | If they match the test is positive. This form of testing will test the correctness of our code. \\ 665 | 666 | The second way is benchmark test to test efficiency. 667 | 668 | %The second way are going to do testing is by benchmark test. This we will do in order to evaluate the efficiency of our code. 669 | 670 | \section{Discussion} 671 | In this section we will discuss benefits and drawbacks with our chosen compilation strategy. 672 | We will discuss how thing can be improved for instance how polymorphism in Futhark could make the compilation easier. 673 | We will also discuss the test results. 674 | Ideas to some themes are: No polymorphism in Futhark yet makes the compilation more difficult and create a lot of duplicate code. 675 | There are no way of really testing the generated code as no parallel backend exists for either TAIL or Futhark. 676 | 677 | \section{Summary and future work} 678 | 679 | 680 | 681 | %%%%%%%%%%% REFERENCES %%%%%%%%%%%%%% 682 | 683 | \bibliography{references}{} 684 | \bibliographystyle{plain} 685 | 686 | There will be more references in the final thesis. 687 | \end{document} 688 | --------------------------------------------------------------------------------