Trimmed monorepo checkout (fluxer_desktop + packages/voice_engine_v2 + tools/ci) with a "Connect to a Different Server" menu item and popout that lets the desktop app switch to any self-hosted Fluxer instance, plus fixes for well-known discovery on single-domain self-hosted deployments and a false-positive ERR_ABORTED on same-origin client redirects during the switch. Defaults to chat.fluxr.chat and uses an isolated userData directory from the official build.
216 lines
6.1 KiB
Rust
216 lines
6.1 KiB
Rust
#![allow(dead_code)]
|
|
use std::time::Instant;
|
|
|
|
use tract_data::prelude::*;
|
|
use tract_linalg::frame::mmm::*;
|
|
|
|
fn ruin_cache() {
|
|
// return;
|
|
let _a = (0..1000000).collect::<Vec<i32>>();
|
|
}
|
|
|
|
pub fn reference<T, K>(mr: usize, k: usize, nr: usize) -> Vec<f32>
|
|
where
|
|
T: Datum + Copy + num_traits::Zero + tract_linalg::LADatum,
|
|
K: MatMatMulKer<T>,
|
|
{
|
|
let mut vi = vec![0.0; k * nr];
|
|
|
|
for m in 0..mr {
|
|
for n in 0..nr {
|
|
for _ in 0..k {
|
|
let a: f32 = 1.0;
|
|
let b = 1.0;
|
|
let offset = { n + m * nr };
|
|
vi[offset] += a * b;
|
|
}
|
|
}
|
|
}
|
|
vi
|
|
}
|
|
|
|
fn bench_to_nanos<
|
|
T: Datum + Copy + num_traits::Zero + tract_linalg::LADatum,
|
|
K: MatMatMulKer<T>,
|
|
>(
|
|
loops: usize,
|
|
m: usize,
|
|
n: usize,
|
|
k: usize,
|
|
) -> f64 {
|
|
let kernel = K::mmm();
|
|
|
|
let mut a = Tensor::zero_aligned::<T>(
|
|
&[(k + K::end_padding_packed_a()) * m],
|
|
K::alignment_bytes_packed_a(),
|
|
)
|
|
.unwrap();
|
|
|
|
let mut a_plain = a.try_as_plain_mut().unwrap();
|
|
let mut v = a_plain.to_array_view_mut::<f32>().unwrap();
|
|
v += 1.0;
|
|
drop(v);
|
|
drop(a_plain);
|
|
let mut b = Tensor::zero_aligned::<T>(
|
|
&[(k + K::end_padding_packed_b()) * n],
|
|
K::alignment_bytes_packed_b(),
|
|
)
|
|
.unwrap();
|
|
|
|
let mut b_plain = b.try_as_plain_mut().unwrap();
|
|
let mut v = b_plain.to_array_view_mut::<f32>().unwrap();
|
|
v += 1.0;
|
|
drop(v);
|
|
drop(b_plain);
|
|
let mut c = Tensor::zero::<T>(&[n, m]).unwrap();
|
|
|
|
let ops = unsafe {
|
|
[
|
|
FusedSpec::AddMatMul {
|
|
k,
|
|
a: kernel.a_packed(4, k).wrap(&a.view()),
|
|
b: kernel.b_packed(4, k).wrap(&b.view()),
|
|
},
|
|
// FusedSpec::AddUnicast(kernel.c_view(1, 0).wrap(&c.view_mut())),
|
|
FusedSpec::Store(kernel.c_view(1, 0).wrap(&c.view_mut())),
|
|
]
|
|
};
|
|
|
|
let mut values = Vec::with_capacity(loops);
|
|
|
|
for _ in 0..loops {
|
|
ruin_cache();
|
|
let start = Instant::now();
|
|
unsafe { kernel.run(m, n, &ops).unwrap() };
|
|
values.push(start.elapsed());
|
|
}
|
|
|
|
eprintln!(
|
|
"{:?} -> {:?}",
|
|
values.first().unwrap(),
|
|
values.last().unwrap()
|
|
);
|
|
|
|
values.sort();
|
|
values[loops / 2].as_nanos() as f64
|
|
}
|
|
|
|
fn model<T: Datum + Copy + num_traits::Zero + tract_linalg::LADatum, K: MatMatMulKer<T>>()
|
|
-> (f64, f64) {
|
|
let x = 1000;
|
|
let zp = bench_to_nanos::<T, K>(1000, K::mr() * 4, K::nr() * 4, 0);
|
|
let y = bench_to_nanos::<T, K>(1000, K::mr() * 4, K::nr() * 4, x);
|
|
let slope = (y - zp) / x as f64;
|
|
(slope, zp)
|
|
}
|
|
|
|
fn as_match_line<T: Datum + Copy + num_traits::Zero + tract_linalg::LADatum, K: MatMatMulKer<T>>() {
|
|
let coeffs = model::<T, K>();
|
|
println!(
|
|
"({:?}, {}, {}) => {} * k + {}",
|
|
K::name(),
|
|
K::mr(),
|
|
K::nr(),
|
|
(coeffs.0),
|
|
(coeffs.1),
|
|
);
|
|
}
|
|
|
|
fn main() {
|
|
let core_id = core_affinity::get_core_ids().unwrap()[0];
|
|
core_affinity::set_for_current(core_id);
|
|
// as_match_line::<f32, fma_mmm_f32_64x1>();
|
|
// as_match_line::<f32, avx512_mmm_f32_128x1>();
|
|
// as_match_line::<f32, avx512_mmm_f32_16x1>();
|
|
// as_match_line::<f32, fma_mmm_f32_40x2>();
|
|
// as_match_line::<f32, fma_mmm_f32_32x3>();
|
|
// as_match_line::<f32, fma_mmm_f32_24x4>();
|
|
// as_match_line::<f32, fma_mmm_f32_16x5>();
|
|
// as_match_line::<f32, fma_mmm_f32_16x6>();
|
|
// as_match_line::<f32, fma_mmm_f32_8x8>();
|
|
|
|
// mmv_perf_m();
|
|
mmm_perf_batch_size();
|
|
}
|
|
|
|
// for mmv
|
|
fn mmv_perf_m() {
|
|
use tract_linalg::x86_64_fma::mmm::*;
|
|
let core_id = core_affinity::get_core_ids().unwrap()[0];
|
|
core_affinity::set_for_current(core_id);
|
|
fn bench<T: Datum + Copy + num_traits::Zero + tract_linalg::LADatum, K: MatMatMulKer<T>>(
|
|
m: usize,
|
|
) {
|
|
let val = bench_to_nanos::<T, K>(1000, m, 1, 100) / (m * 100) as f64;
|
|
print!("{val}\t");
|
|
}
|
|
|
|
print!("N\t");
|
|
print!("fma_mmm_f32_64x1\t");
|
|
print!("avx512_mmm_f32_128x1\t");
|
|
print!("avx512_mmm_f32_16x1\t");
|
|
println!();
|
|
for n in 1..=128 {
|
|
eprintln!("{n}");
|
|
print!("{n}\t");
|
|
bench::<f32, fma_mmm_f32_64x1>(n);
|
|
bench::<f32, avx512_mmm_f32_128x1>(n);
|
|
bench::<f32, avx512_mmm_f32_16x1>(n);
|
|
println!();
|
|
}
|
|
}
|
|
|
|
// output a csv file with the perf of the kernels wrt batch size
|
|
fn mmm_perf_batch_size() {
|
|
use tract_linalg::x86_64_fma::mmm::*;
|
|
let core_id = core_affinity::get_core_ids().unwrap()[0];
|
|
core_affinity::set_for_current(core_id);
|
|
fn bench<T: Datum + Copy + num_traits::Zero + tract_linalg::LADatum, K: MatMatMulKer<T>>(
|
|
n: usize,
|
|
) {
|
|
let val =
|
|
bench_to_nanos::<T, K>(1000, K::mr() * 4, n, 100) / (K::mr() * 4 * 100 * n) as f64;
|
|
print!("{val}\t");
|
|
}
|
|
|
|
print!("N\t");
|
|
print!("fma_mmm_f32_8x8\t");
|
|
print!("fma_mmm_f32_16x6\t");
|
|
print!("fma_mmm_f32_16x5\t");
|
|
print!("fma_mmm_f32_24x4\t");
|
|
print!("fma_mmm_f32_32x3\t");
|
|
print!("fma_mmm_f32_40x2\t");
|
|
print!("fma_mmm_f32_64x1\t");
|
|
print!("avx512_mmm_f32_128x1\t");
|
|
print!("avx512_mmm_f32_16x1\t");
|
|
print!("avx512_mmm_f32_16x12\t");
|
|
print!("avx512_mmm_f32_16x8\t");
|
|
print!("avx512_mmm_f32_32x6\t");
|
|
print!("avx512_mmm_f32_32x5\t");
|
|
print!("avx512_mmm_f32_48x4\t");
|
|
print!("avx512_mmm_f32_64x3\t");
|
|
print!("avx512_mmm_f32_80x2\t");
|
|
println!();
|
|
for n in 1..=128 {
|
|
eprintln!("{n}");
|
|
print!("{n}\t");
|
|
bench::<f32, fma_mmm_f32_8x8>(n);
|
|
bench::<f32, fma_mmm_f32_16x6>(n);
|
|
bench::<f32, fma_mmm_f32_16x5>(n);
|
|
bench::<f32, fma_mmm_f32_24x4>(n);
|
|
bench::<f32, fma_mmm_f32_32x3>(n);
|
|
bench::<f32, fma_mmm_f32_40x2>(n);
|
|
bench::<f32, fma_mmm_f32_64x1>(n);
|
|
bench::<f32, avx512_mmm_f32_128x1>(n);
|
|
bench::<f32, avx512_mmm_f32_16x1>(n);
|
|
bench::<f32, avx512_mmm_f32_16x12>(n);
|
|
bench::<f32, avx512_mmm_f32_16x8>(n);
|
|
bench::<f32, avx512_mmm_f32_32x6>(n);
|
|
bench::<f32, avx512_mmm_f32_32x5>(n);
|
|
bench::<f32, avx512_mmm_f32_48x4>(n);
|
|
bench::<f32, avx512_mmm_f32_64x3>(n);
|
|
bench::<f32, avx512_mmm_f32_80x2>(n);
|
|
println!();
|
|
}
|
|
}
|