cholesky_native.jl 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. using LinearAlgebra
  2. function check(mat::Matrix{Float32})
  3. size_p = size(mat, 1)
  4. for i in 1:size_p
  5. for j in 1:size_p
  6. if j < i
  7. mat[i, j] = 0.0f0
  8. end
  9. end
  10. end
  11. test_mat ::Matrix{Float32} = zeros(Float32, size_p, size_p)
  12. BLAS.syrk!('L', 'T', 1.0f0, mat, 0.0f0, test_mat)
  13. for i in 1:size_p
  14. for j in 1:size_p
  15. if j <= i
  16. orig = (1.0f0/(1.0f0+(i-1)+(j-1))) + ((i == j) ? 1.0f0*size_p : 0.0f0)
  17. err = abs(test_mat[i,j] - orig) / orig
  18. if err > 0.0001
  19. got = test_mat[i,j]
  20. expected = orig
  21. error("[$i, $j] -> $got != $expected (err $err)")
  22. end
  23. end
  24. end
  25. end
  26. println(stderr, "Verification successful !")
  27. end
  28. function main(size_p :: Int; verify = false, verbose = false)
  29. mat = zeros(Float32, size_p, size_p)
  30. # create a simple definite positive symetric matrix
  31. # Hilbert matrix h(i,j) = 1/(i+j+1)
  32. for i in 1:size_p
  33. for j in 1:size_p
  34. mat[i, j] = 1.0f0 / (1.0f0+(i-1)+(j-1)) + ((i == j) ? 1.0f0*size_p : 0.0f0)
  35. end
  36. end
  37. if verbose
  38. display(mat)
  39. end
  40. t_start = time_ns()
  41. cholesky!(mat)
  42. t_end = time_ns()
  43. flop = (1.0*size_p*size_p*size_p)/3.0
  44. time_ms = (t_end-t_start) / 1e6
  45. gflops = flop/(time_ms*1000)/1000
  46. println("$size_p\t$time_ms\t$gflops")
  47. if verbose
  48. display(mat)
  49. end
  50. if verify
  51. check(mat)
  52. end
  53. end
  54. println("# size\tms\tGFlops")
  55. if length(ARGS) > 0 && ARGS[1] == "-quickcheck"
  56. main(1024, verify = true)
  57. else
  58. for size in 1024:1024:15360
  59. main(size)
  60. end
  61. end