NB. Dot Product Benchmark: Native J vs Futhark NB. Compares performance on extremely large arrays load '/path/to/futhark.ijs' NB. =============================================================== NB. Dot Product Implementations NB. =============================================================== NB. Native J dot product: +/ x * y j_dot =: +/@:* NB. Futhark dot product (dyadic - takes two vectors directly) NB. Now supports proper dyadic verbs: x fut_dot y fut_dot =: 'entry f (xs: []f64) (ys: []f64) : f64 = reduce (+) 0 (map2 (*) xs ys)' fut NB. =============================================================== NB. Benchmark Utility NB. =============================================================== NB. =============================================================== NB. Run Benchmarks NB. =============================================================== echo '' echo '=================================================================' echo ' DOT PRODUCT BENCHMARK: Native J vs Futhark' echo '=================================================================' echo ' dot(a,b) = sum(a * b)' echo ' J: +/ a * b' echo ' Futhark: reduce (+) 0 (map2 (*) a b)' echo '=================================================================' echo '' echo 'Backend: ', FUTHARK_BACKEND, ' Threads: ', ": FUTHARK_THREADS echo '' NB. Test sizes sizes =: 100000 500000 1000000 2000000 5000000 10000000 100000000 echo 'Size J (ms) Futhark (ms) Speedup Match' echo '--------- -------- ------------ ------- -----' run_bench =: 3 : 0 n =. y NB. Generate random vectors a =. n ?@$ 0 b =. n ?@$ 0 NB. Run multiple times and average runs =. 5 NB. J timing j_total =. 0 for_r. i. runs do. t0 =. 6!:1 '' j_result =. a j_dot b t1 =. 6!:1 '' j_total =. j_total + 1000 * t1 - t0 end. j_ms =. j_total % runs NB. Futhark timing (now using natural dyadic syntax: a fut_dot b) fut_total =. 0 for_r. i. runs do. t0 =. 6!:1 '' fut_result =. a fut_dot b t1 =. 6!:1 '' fut_total =. fut_total + 1000 * t1 - t0 end. fut_ms =. fut_total % runs NB. Check results match (within floating point tolerance) tol =. 1e_6 * | j_result match =. tol > | j_result - fut_result NB. Calculate speedup (Futhark speedup over J) speedup =. j_ms % fut_ms >. 0.001 NB. Format output size_s =. 10 {. ": n j_s =. 10 {. 8j2 ": j_ms fut_s =. 12 {. 8j2 ": fut_ms spd_s =. 8 {. (5j2 ": speedup), 'x' match_s =. > match { 'FAIL';'OK ' echo size_s, ' ', j_s, ' ', fut_s, ' ', spd_s, ' ', match_s j_ms, fut_ms, speedup, match ) results =: run_bench"0 sizes echo '' echo '=================================================================' echo 'ANALYSIS:' echo '' echo ' Dot product is a SIMPLE, MEMORY-BOUND operation:' echo ' - Only 2 FLOPs per element (multiply + add)' echo ' - Performance limited by memory bandwidth, not CPU' echo ' - J''s native +/@:* is highly optimized for this' echo '' echo ' Futhark overhead includes:' echo ' - FFI boundary crossing' echo ' - Memory allocation and data copying' echo ' - Thread synchronization' echo '' echo ' For simple operations like dot product, native J wins.' echo ' Futhark excels at COMPUTE-BOUND operations where the' echo ' computation per element is much higher (e.g., stencils,' echo ' complex reductions, nested parallelism).' echo '' echo ' Try the stddev benchmark for a more complex operation' echo ' where Futhark can better amortize its overhead.' echo '=================================================================' exit 0