Experiments with Clojure / Sumatra / Graal and, ultimately, Clojure compiled onto GPGPU...
For Fedora 20 / x86_64 - see https://wiki.openjdk.java.net/display/Sumatra/Sumatra+JDK+build+instructions for more detail / alternative architectures
You'll need to ensure that a few packages are installed - do the following as root:
yum install java-1.7.0-openjdk mercurial freetype-devel cups-devel gcc gcc-c++ p7zip p7zip-plugins ccache libstdc++-static maven yum-builddep java-1.7.0-openjdk
Build yourself a graal-enabled jdk8 on which to run Clumatra
This may take 30 mins or so and will create a large subdir called 'graal'
./bin/build-graal.sh
Install the okra jar in your local maven / lein repository
mvn install:install-file -DgroupId=com.amd -DartifactId=okra -Dversion=1.8 -Dpackaging=jar -Dfile=./graal/graal/lib/okra-1.8.jar mvn install:install-file -DgroupId=com.amd -DartifactId=okra-with-sim -Dversion=1.8 -Dpackaging=jar -Dfile=./graal/graal/lib/okra-1.8-with-sim.jar
You'll need lein - build and run Clumatra tests on graal-enabled jdk8
./bin/env.sh lein test
The output should look something like this. It includes the source disassembled Java bytecode and target HSAIL for reference. I have added "-Dclumatra.verbose=true" flag in the project.clj. If you would prefer terse test output, just set this to false.
lein test Initializing NoDisassemble Transformer [HSAIL] library is libokra_x86_64.so [HSAIL] using _OKRA_SIM_LIB_PATH_=/tmp/okraresource.dir_75590013030364124/libokra_x86_64.so [GPU] registered initialization of Okra (total initialized: 1) *** TESTING WITH OKRA *** Reflection warning, no/disassemble.clj:10:3 - call to method replace can't be resolved (target class is unknown). Reflection warning, no/disassemble.clj:21:28 - reference to field getCanonicalName can't be resolved. Reflection warning, no/disassemble.clj:23:5 - call to method disassemble on org.eclipse.jdt.internal.core.util.Disassembler can't be resolved (argument types: java.lang.Object, java.lang.String, unknown). lein test clojure.lang-test "Elapsed time: 0.436649 msecs" "Elapsed time: 0.775219 msecs" lein test clumatra.core-test OKRA: SIMULATED // Compiled from core_test.clj (version 1.5 : 49.0, super bit) public final class clumatra.core_test$fn$reify__1024 implements clumatra.core_test.LongKernel, clojure.lang.IObj { // Field descriptor #11 Lclojure/lang/Var; public static final clojure.lang.Var const__0; // Field descriptor #11 Lclojure/lang/Var; public static final clojure.lang.Var const__1; // Field descriptor #11 Lclojure/lang/Var; public static final clojure.lang.Var const__2; // Field descriptor #39 Lclojure/lang/IPersistentMap; final clojure.lang.IPersistentMap __meta; // Method descriptor #15 ()V // Stack: 2, Locals: 0 public static {}; 0 ldc [17] 2 ldc [19] 4 invokestatic clojure.lang.RT.var(java.lang.String, java.lang.String) : clojure.lang.Var [25] 7 checkcast clojure.lang.Var [27] 10 putstatic clumatra.core_test$fn$reify__1024.const__0 : clojure.lang.Var [29] 13 ldc [17] 15 ldc [31] 17 invokestatic clojure.lang.RT.var(java.lang.String, java.lang.String) : clojure.lang.Var [25] 20 checkcast clojure.lang.Var [27] 23 putstatic clumatra.core_test$fn$reify__1024.const__1 : clojure.lang.Var [33] 26 ldc [17] 28 ldc [35] 30 invokestatic clojure.lang.RT.var(java.lang.String, java.lang.String) : clojure.lang.Var [25] 33 checkcast clojure.lang.Var [27] 36 putstatic clumatra.core_test$fn$reify__1024.const__2 : clojure.lang.Var [37] 39 return Line numbers: [pc: 0, line: 107] // Method descriptor #41 (Lclojure/lang/IPersistentMap;)V // Stack: 2, Locals: 2 public core_test$fn$reify__1024(clojure.lang.IPersistentMap arg0); 0 aload_0 1 invokespecial java.lang.Object() [43] 4 aload_0 5 aload_1 6 putfield clumatra.core_test$fn$reify__1024.__meta : clojure.lang.IPersistentMap [45] 9 return Line numbers: [pc: 0, line: 107] // Method descriptor #15 ()V // Stack: 2, Locals: 1 public core_test$fn$reify__1024(); 0 aload_0 1 aconst_null 2 invokespecial clumatra.core_test$fn$reify__1024(clojure.lang.IPersistentMap) [47] 5 return // Method descriptor #49 ()Lclojure/lang/IPersistentMap; // Stack: 1, Locals: 1 public clojure.lang.IPersistentMap meta(); 0 aload_0 1 getfield clumatra.core_test$fn$reify__1024.__meta : clojure.lang.IPersistentMap [45] 4 areturn // Method descriptor #51 (Lclojure/lang/IPersistentMap;)Lclojure/lang/IObj; // Stack: 3, Locals: 2 public clojure.lang.IObj withMeta(clojure.lang.IPersistentMap arg0); 0 new clumatra.core_test$fn$reify__1024 [2] 3 dup 4 aload_1 5 invokespecial clumatra.core_test$fn$reify__1024(clojure.lang.IPersistentMap) [47] 8 areturn // Method descriptor #53 ([J[JI)V // Stack: 6, Locals: 4 public void invoke(long[] in, long[] out, int gid); 0 aload_2 [out] 1 aconst_null 2 astore_2 [out] 3 checkcast long[] [55] 6 iload_3 [gid] 7 nop 8 aload_1 [in] 9 aconst_null 10 astore_1 [in] 11 checkcast long[] [55] 14 iload_3 [gid] 15 nop 16 laload 17 lconst_1 18 ladd 19 invokestatic clojure.lang.RT.aset(long[], int, long) : long [58] 22 invokestatic clojure.lang.Numbers.num(long) : java.lang.Number [64] 25 pop 26 return Line numbers: [pc: 0, line: 107] [pc: 0, line: 109] [pc: 6, line: 109] [pc: 8, line: 109] [pc: 8, line: 109] [pc: 14, line: 109] Local variable table: [pc: 0, pc: 26] local: this index: 0 type: clumatra.core_test.fn.reify__1024 [pc: 0, pc: 26] local: in index: 1 type: long[] [pc: 0, pc: 26] local: out index: 2 type: long[] [pc: 0, pc: 26] local: gid index: 3 type: int } Profiling info for clumatra.core_test$fn$reify__1024.invoke(long[], long[], int) canBeStaticallyBound: false Profiling info for clojure.lang.RT.aset(long[], int, long) canBeStaticallyBound: true Profiling info for clojure.lang.Numbers.num(long) canBeStaticallyBound: true Profiling info for com.oracle.graal.replacements.BoxingSubstitutions$LongSubstitutions.valueOf(long) canBeStaticallyBound: true Fixed Hsail is ============== version 0:95: $full : $large; // instance method HotSpotMethod kernel &run ( align 8 kernarg_u64 %_this, align 8 kernarg_u64 %_arg1, align 8 kernarg_u64 %_arg2 ) { ld_kernarg_u64 $d0, [%_this]; ld_kernarg_u64 $d1, [%_arg1]; ld_kernarg_u64 $d2, [%_arg2]; workitemabsid_u32 $s0, 0; @L0: cmp_eq_b1_u64 $c0, $d2, 0; // null test cbr $c0, @L1; @L2: ld_global_s32 $s1, [$d2 + 12]; cmp_ge_b1_u32 $c0, $s0, $s1; cbr $c0, @L10; @L3: ld_global_s32 $s1, [$d2 + 12]; cmp_ge_b1_u32 $c0, $s0, $s1; cbr $c0, @L9; @L4: cmp_eq_b1_u64 $c0, $d1, 0; // null test cbr $c0, @L5; @L6: ld_global_s32 $s1, [$d1 + 12]; cmp_ge_b1_u32 $c0, $s0, $s1; cbr $c0, @L8; @L7: cvt_s64_s32 $d0, $s0; mul_s64 $d0, $d0, 8; add_u64 $d1, $d1, $d0; ld_global_s64 $d0, [$d1 + 16]; add_s64 $d0, $d0, 0x1; cvt_s64_s32 $d1, $s0; mul_s64 $d1, $d1, 8; add_u64 $d2, $d2, $d1; st_global_s64 $d0, [$d2 + 16]; ret; @L1: mov_b32 $s0, -11; @L11: ret; @L9: mov_b32 $s0, -92; brn @L11; @L8: mov_b32 $s0, -27; brn @L11; @L10: mov_b32 $s0, -27; brn @L11; @L5: mov_b32 $s0, -11; brn @L11; }; spawning Program: hsailasm temp_hsa.hsail -g -o temp_hsa.o hsailasm succeeded createProgram succeeded createKernel succeeded level 0, grid=32, group=1 pushPointerArg, addr=0 pushPointerArg, addr=0 pushPointerArg, addr=0 setPointerArg, addr=0xc0390088 setPointerArg, addr=0xc0718188 setPointerArg, addr=0xc07182c0 (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31) -> (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32) ...
If you want tun run up a dev environment, start it via the env.sh script - e.g.
./bin/env.sh emacs
to get JAVA_HOME etc set up
That's it for the moment - more as and when.
Copyright © 2014 Julian Gosnell
Distributed under the Eclipse Public License, the same as Clojure.