-module(viva_tensor@native@blas). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/viva_tensor/native/blas.gleam"). -export([detect_backend/0, get_cpu_topology/0, configure_threads/1, set_affinity/1, auto_configure/0, backend_name/1, expected_gflops/2]). -export_type([blas_backend/0, cpu_topology/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC(false). -type blas_backend() :: intel_m_k_l | open_b_l_a_s | zig_s_i_m_d | unknown. -type cpu_topology() :: {cpu_topology, integer(), integer(), integer(), integer(), boolean(), boolean()}. -file("src/viva_tensor/native/blas.gleam", 34). ?DOC(false). -spec detect_backend() -> blas_backend(). detect_backend() -> viva_tensor_blas:detect_backend(). -file("src/viva_tensor/native/blas.gleam", 38). ?DOC(false). -spec get_cpu_topology() -> cpu_topology(). get_cpu_topology() -> viva_tensor_blas:get_cpu_topology(). -file("src/viva_tensor/native/blas.gleam", 42). ?DOC(false). -spec configure_threads(integer()) -> {ok, nil} | {error, binary()}. configure_threads(Num_threads) -> viva_tensor_blas:configure_threads(Num_threads). -file("src/viva_tensor/native/blas.gleam", 46). ?DOC(false). -spec set_affinity(binary()) -> {ok, nil} | {error, binary()}. set_affinity(Mode) -> viva_tensor_blas:set_affinity(Mode). -file("src/viva_tensor/native/blas.gleam", 49). ?DOC(false). -spec auto_configure() -> {ok, blas_backend()} | {error, binary()}. auto_configure() -> Backend = viva_tensor_blas:detect_backend(), Topo = viva_tensor_blas:get_cpu_topology(), Optimal_threads = erlang:element(3, Topo), case viva_tensor_blas:configure_threads(Optimal_threads) of {ok, _} -> case viva_tensor_blas:set_affinity(<<"scatter"/utf8>>) of {ok, _} -> {ok, Backend}; {error, E} -> {error, E} end; {error, E@1} -> {error, E@1} end. -file("src/viva_tensor/native/blas.gleam", 69). ?DOC(false). -spec backend_name(blas_backend()) -> binary(). backend_name(Backend) -> case Backend of intel_m_k_l -> <<"Intel MKL (800+ GFLOPS)"/utf8>>; open_b_l_a_s -> <<"OpenBLAS DYNAMIC_ARCH (500+ GFLOPS)"/utf8>>; zig_s_i_m_d -> <<"Zig SIMD GEMM (400+ GFLOPS)"/utf8>>; unknown -> <<"Unknown"/utf8>> end. -file("src/viva_tensor/native/blas.gleam", 79). ?DOC(false). -spec expected_gflops(blas_backend(), integer()) -> integer(). expected_gflops(Backend, Matrix_size) -> case Backend of intel_m_k_l -> case Matrix_size of S when S >= 4000 -> 800; S@1 when S@1 >= 2000 -> 600; S@2 when S@2 >= 1000 -> 450; _ -> 300 end; open_b_l_a_s -> case Matrix_size of S@3 when S@3 >= 4000 -> 500; S@4 when S@4 >= 2000 -> 400; S@5 when S@5 >= 1000 -> 300; _ -> 200 end; zig_s_i_m_d -> case Matrix_size of S@6 when S@6 >= 4000 -> 450; S@7 when S@7 >= 2000 -> 350; S@8 when S@8 >= 1000 -> 250; _ -> 150 end; unknown -> 100 end.