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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Copyright 2024 Ulvetanna Inc.

use crate::{
	as_packed_field::{PackScalar, PackedType},
	Field, PackedField,
};
use cfg_if::cfg_if;

pub trait ArchOptimal: Field {
	type OptimalThroughputPacked: PackedField<Scalar = Self>;
}

impl<F> ArchOptimal for F
where
	F: Field,
	OptimalUnderlier: PackScalar<F>,
{
	type OptimalThroughputPacked = PackedType<OptimalUnderlier, F>;
}

cfg_if! {
	if #[cfg(all(target_arch = "x86_64", target_feature = "avx512f"))] {
		pub const OPTIMAL_ALIGNMENT: usize = 512;

		pub type OptimalUnderlier128b = crate::arch::x86_64::m128::M128;
		pub type OptimalUnderlier256b = crate::arch::x86_64::m256::M256;
		pub type OptimalUnderlier512b = crate::arch::x86_64::m512::M512;
		pub type OptimalUnderlier = OptimalUnderlier512b;
	} else if #[cfg(all(target_arch = "x86_64", target_feature = "avx2"))] {
		use crate::underlier::ScaledUnderlier;

		pub const OPTIMAL_ALIGNMENT: usize = 256;

		pub type OptimalUnderlier128b = crate::arch::x86_64::m128::M128;
		pub type OptimalUnderlier256b = crate::arch::x86_64::m256::M256;
		pub type OptimalUnderlier512b = ScaledUnderlier<OptimalUnderlier256b, 2>;
		pub type OptimalUnderlier = OptimalUnderlier256b;
	} else if #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] {
		use crate::underlier::ScaledUnderlier;

		pub const OPTIMAL_ALIGNMENT: usize = 128;

		pub type OptimalUnderlier128b = crate::arch::x86_64::m128::M128;
		pub type OptimalUnderlier256b = ScaledUnderlier<OptimalUnderlier128b, 2>;
		pub type OptimalUnderlier512b = ScaledUnderlier<OptimalUnderlier256b, 2>;
		pub type OptimalUnderlier = OptimalUnderlier128b;
	} else if #[cfg(all(target_arch = "aarch64", target_feature = "neon", target_feature = "aes"))] {
		use crate::underlier::ScaledUnderlier;

		pub const OPTIMAL_ALIGNMENT: usize = 128;

		pub type OptimalUnderlier128b = crate::arch::aarch64::m128::M128;
		pub type OptimalUnderlier256b = ScaledUnderlier<OptimalUnderlier128b, 2>;
		pub type OptimalUnderlier512b = ScaledUnderlier<OptimalUnderlier256b, 2>;
		pub type OptimalUnderlier = OptimalUnderlier128b;
	} else {
		use crate::underlier::ScaledUnderlier;

		pub const OPTIMAL_ALIGNMENT: usize = 128;

		pub type OptimalUnderlier128b = u128;
		pub type OptimalUnderlier256b = ScaledUnderlier<OptimalUnderlier128b, 2>;
		pub type OptimalUnderlier512b = ScaledUnderlier<OptimalUnderlier256b, 2>;
		pub type OptimalUnderlier = OptimalUnderlier128b;
	}
}