我如何专门研究特质功能?(How do I specialize a trait function?)

编程入门 行业动态 更新时间:2024-10-25 16:17:05
我如何专门研究特质功能?(How do I specialize a trait function?)

我有BLAS功能的特点:

pub trait Blas { fn gemv<F>(&self, trans: Transpose, cols: usize, rows: usize, matrix: &[F], matrix_factor: F, vector: &[F], vector_inc: usize, vector_factor: F, result: &[F], result_inc: usize) -> Result<(), Error>; ... }

现在我想制作一个实现这个特性的类型:

pub struct CudaBlas { ... } impl Blas for CudaBlas { ... }

问题是我需要针对gemv<f32>和gemv<f64>单gemv<f64> :每个应该调用专用的共享库函数。 没有编译器的投诉,没有成功表达这一点。 我怎样才能做到这一点?

更新:

我尝试了Jonas Tepe提出的方法 ,但它似乎并不奏效。 这是纯化的例子:

trait Trait<T> { fn func(&self, arg: T); } struct Struct { field: usize, } impl Trait<f32> for Struct { fn func(&self, arg: f32) { println!("32bits: {}", arg); } } impl Trait<f64> for Struct { fn func(&self, arg: f64) { println!("64bits: {}", arg); } } struct Struct2<T> { field2: T, } // yes, I plan to use my CudaBlas inside some generic NeuralNet<T> impl<T> Struct2<T> { fn func2(&self, arg: T) { let s = Struct{field: 1}; s.func(arg); } } fn main() { let s32 = Struct2::<f32>{field2: 1f32}; let s64 = Struct2::<f64>{field2: 2f64}; s32.func2(1f32); s64.func2(1f64); }

我明白了:

错误:特征Trait<T>没有为类型Struct [E0277]实现

使Struct是通用的并不能解决问题(编译器抱怨说,类型Struct<T>没有找到func )。 只是惊讶于Rust仿制药的限制性。

I have a trait for BLAS functionality:

pub trait Blas { fn gemv<F>(&self, trans: Transpose, cols: usize, rows: usize, matrix: &[F], matrix_factor: F, vector: &[F], vector_inc: usize, vector_factor: F, result: &[F], result_inc: usize) -> Result<(), Error>; ... }

Now I want to make a type which implements this trait:

pub struct CudaBlas { ... } impl Blas for CudaBlas { ... }

The problem is that I need separate specialisations for gemv<f32> and gemv<f64>: each one should call a dedicated shared library function. Didn't succeed to express that without compiler complaints. How can I achieve that?

UPDATE:

I tried the method proposed by Jonas Tepe and it doesn't seem to work. Here is the purified example:

trait Trait<T> { fn func(&self, arg: T); } struct Struct { field: usize, } impl Trait<f32> for Struct { fn func(&self, arg: f32) { println!("32bits: {}", arg); } } impl Trait<f64> for Struct { fn func(&self, arg: f64) { println!("64bits: {}", arg); } } struct Struct2<T> { field2: T, } // yes, I plan to use my CudaBlas inside some generic NeuralNet<T> impl<T> Struct2<T> { fn func2(&self, arg: T) { let s = Struct{field: 1}; s.func(arg); } } fn main() { let s32 = Struct2::<f32>{field2: 1f32}; let s64 = Struct2::<f64>{field2: 2f64}; s32.func2(1f32); s64.func2(1f64); }

I get:

error: the trait Trait<T> is not implemented for the type Struct [E0277]

Making Struct to be generic doesn't solve the problem as well (the compiler complaints that func is not found for type Struct<T>). Just amazed how restrictive the Rust generics are.

最满意答案

一种解决方案是让你的特质Blas通用于浮点类型,然后为你的CudaBlas struct有两个独立的特性实现:

pub trait Blas<F> { fn gemv(&self, trans: Transpose, cols: usize, rows: usize, matrix: &[F], matrix_factor: F, vector: &[F], vector_inc: usize, vector_factor: F, result: &[F], result_inc: usize) -> Result<(), Error>; ... } impl Blas<f32> for CudaBlas { fn gemv(&self, trans: Transpose, cols: usize, rows: usize, matrix: &[f32], matrix_factor: f32, vector: &[f32], vector_inc: usize, vector_factor: f32, result: &[f32], result_inc: usize) -> Result<(), Error> { // implement f32 specific functionality } } impl Blas<f64> for CudaBlas { fn gemv(&self, trans: Transpose, cols: usize, rows: usize, matrix: &[f64], matrix_factor: f64, vector: &[f64], vector_inc: usize, vector_factor: f64, result: &[f64], result_inc: usize) -> Result<(), Error> { // implement f64 specific functionality } }

之后,您可以使用f32或f64在CudaBlas上调用方法gemv() ,每次都使用所需的特定类型结果。

All I needed is to add where CudaBlas: Blas<T>:

#![allow(dead_code, unused_variables)] trait Blas<T> { fn gemv(&self, arg: T); } struct CudaBlas { field: usize, } impl Blas<f32> for CudaBlas { fn gemv(&self, arg: f32) { println!("f32"); } } impl Blas<f64> for CudaBlas { fn gemv(&self, arg: f64) { println!("f64"); } } struct NeuralNet<T> { field: T, } impl<T> NeuralNet<T> { fn process(&self, arg: T) where CudaBlas: Blas<T> { let cblas = CudaBlas{field:0}; cblas.gemv(arg); } } fn main() { let nn = NeuralNet{field:0f64}; nn.process(12f64); }

更多推荐

本文发布于:2023-07-16 13:32:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1129034.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:特质   功能   specialize   trait   function

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!