Rust 无法创建默认特性实现
我正在尝试实现一个向量数学库,它可以根据处理器支持的功能集生成函数的SIMD优化版本。目前,我有一个用于每个功能集的结构和一个定义回退结构的特征。我在功能集结构上实现每个操作。我无法实施回退机制。我现在所做的产生了流动误差Rust 无法创建默认特性实现,rust,Rust,我正在尝试实现一个向量数学库,它可以根据处理器支持的功能集生成函数的SIMD优化版本。目前,我有一个用于每个功能集的结构和一个定义回退结构的特征。我在功能集结构上实现每个操作。我无法实施回退机制。我现在所做的产生了流动误差 error[E0119]: conflicting implementations of trait `Add<Vec4, Vec4>` for type `Scalar`: --> src/main.rs:41:1 | 14 | default
error[E0119]: conflicting implementations of trait `Add<Vec4, Vec4>` for type `Scalar`:
--> src/main.rs:41:1
|
14 | default impl<F: FeatureSet, Lhs, Rhs> Add<Lhs, Rhs> for F where <F as FeatureSet>::Fallback: Add<Lhs, Rhs> {
| ---------------------------------------------------------------------------------------------------------- first implementation here
...
41 | impl Add<Vec4, Vec4> for Scalar {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Scalar`
error[E0119]:类型“Scalar”的trait“Add”的实现冲突:
-->src/main.rs:41:1
|
14 | F的默认impl Add,其中::Fallback:Add{
|-----------------------------------------------------------------------------------------这里的第一个实现
...
41 |针对标量的impl Add{
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^标量的冲突实现`
有人对如何解决这个问题有什么建议吗
示例代码:
#![feature(specialization)]
use std::arch::x86_64 as arch;
trait FeatureSet {
type Fallback;
}
trait Add<Lhs, Rhs> {
type Output;
unsafe fn add(lhs: Lhs, rhs: Rhs) -> Self::Output;
}
// Attempt at implementing fallback to implementation in Fallback type
default impl<F: FeatureSet, Lhs, Rhs> Add<Lhs, Rhs> for F where <F as FeatureSet>::Fallback: Add<Lhs, Rhs> {
type Output = <<F as FeatureSet>::Fallback as Add<Lhs, Rhs>>::Output;
unsafe fn add(lhs: Lhs, rhs: Rhs) -> Self::Output {
<F as FeatureSet>::Fallback::add(lhs, rhs)
}
}
#[repr(C)]
union Vec4 {
scalar: std::mem::ManuallyDrop<[f32; 4]>,
#[allow(unused)]
simd: std::mem::ManuallyDrop<arch::__m128>,
}
impl std::convert::From<[f32; 4]> for Vec4 {
fn from(values: [f32; 4]) -> Self {
Self {
scalar: std::mem::ManuallyDrop::new(values)
}
}
}
struct Scalar;
impl FeatureSet for Scalar {
type Fallback = ();
}
impl Add<Vec4, Vec4> for Scalar {
type Output = Vec4;
unsafe fn add(lhs: Vec4, rhs: Vec4) -> Self::Output {
let mut r: [f32; 4] = std::mem::MaybeUninit::uninit().assume_init();
for i in 0 .. 4 {
r[i] = lhs.scalar[i] + rhs.scalar[i];
}
r.into()
}
}
struct Sse;
impl FeatureSet for Sse {
type Fallback = Scalar;
}
// Should fall back to implementation in FeatureSet::Fallback type when not implemented
impl Add<Vec4, Vec4> for Sse {
type Output = Vec4;
#[inline]
#[target_feature(enable = "sse")]
unsafe fn add(lhs: Vec4, rhs: Vec4) -> Self::Output {
let r = arch::_mm_add_ps(*lhs.simd, *rhs.simd);
Vec4 {
simd: std::mem::ManuallyDrop::new(r)
}
}
}
#[inline(never)]
// This function should be able to be specialized for each feature set for later
// runtime selection
unsafe fn perform_add<F: FeatureSet>(a: Vec4, b: Vec4) -> Vec4 {
F::add(a, b)
}
fn main() {
let a = [0.0, 1.0, 2.0, 3.0].into();
let b = [4.0, 4.0, 5.0, 6.0].into();
unsafe {
let c = perform_add::<Sse>(a, b);
println!("{} {} {} {}", c.scalar[0], c.scalar[1], c.scalar[2], c.scalar[3]);
}
}
#![功能(专业化)]
使用std::arch::x86_64作为arch;
特征集{
类型回退;
}
性状加{
类型输出;
不安全的fn添加(lhs:lhs,rhs:rhs)->自::输出;
}
//尝试在回退类型中实现回退到实现
F的默认impl-Add,其中::Fallback:Add{
类型输出=::输出;
不安全fn添加(lhs:lhs,rhs:rhs)->自::输出{
::后备::添加(左、右)
}
}
#[报告员(C)]
联合Vec4{
标量:std::mem::ManuallyDrop,
#[允许(未使用)]
simd:std::mem::ManuallyDrop,
}
Vec4的impl std::convert::From{
fn from(值:[f32;4])->Self{
自我{
标量:std::mem::ManuallyDrop::new(值)
}
}
}
结构标量;
标量的impl特性集{
类型Fallback=();
}
标量的impl Add{
类型输出=Vec4;
不安全的fn添加(lhs:Vec4,rhs:Vec4)->自::输出{
让mut r:[f32;4]=std::mem::maybeunit::uninit();
因为我在0..4{
r[i]=lhs.标量[i]+rhs.标量[i];
}
r、 变成
}
}
结构Sse;
Sse的impl功能集{
类型回退=标量;
}
//未实现时,应退回到FeatureSet::Fallback类型中的实现
Sse的impl Add{
类型输出=Vec4;
#[内联]
#[目标功能(enable=“sse”)]
不安全的fn添加(lhs:Vec4,rhs:Vec4)->自::输出{
设r=arch::_mm_add_ps(*lhs.simd,*rhs.simd);
Vec4{
simd:std::mem::ManuallyDrop::new(r)
}
}
}
#[在线(从不)]
//此功能应能够专门用于以后的每个功能集
//运行时选择
不安全fn执行添加(a:Vec4,b:Vec4)->Vec4{
F::添加(a,b)
}
fn main(){
设a=[0.0,1.0,2.0,3.0].into();
设b=[4.0,4.0,5.0,6.0].into();
不安全{
设c=执行_添加::(a,b);
println!(“{}{}{}}”,c.scalar[0],c.scalar[1],c.scalar[2],c.scalar[3]);
}
}
我知道这不能回答您的问题,但是,您应该切换到minu-specialization
(如果可能)。我希望可以,但是minu-specialization
似乎不支持相关类型。