gpt4 book ai didi

matrix - 是否可以编写一个可以转置矩阵的rust宏?

转载 作者:行者123 更新时间:2023-12-03 11:43:17 25 4
gpt4 key购买 nike

我目前正在使用SIMD处理optimizing the rust jpeg decoder crate。为了避免代码中的长时间重复,我想编写一个生成以下矩阵转置代码的宏:

s = [
i32x8::new(s[0].extract(0),s[1].extract(0),s[2].extract(0),s[3].extract(0),s[4].extract(0),s[5].extract(0),s[6].extract(0),s[7].extract(0), ),
i32x8::new(s[0].extract(1),s[1].extract(1),s[2].extract(1),s[3].extract(1),s[4].extract(1),s[5].extract(1),s[6].extract(1),s[7].extract(1), ),
i32x8::new(s[0].extract(2),s[1].extract(2),s[2].extract(2),s[3].extract(2),s[4].extract(2),s[5].extract(2),s[6].extract(2),s[7].extract(2), ),
i32x8::new(s[0].extract(3),s[1].extract(3),s[2].extract(3),s[3].extract(3),s[4].extract(3),s[5].extract(3),s[6].extract(3),s[7].extract(3), ),
i32x8::new(s[0].extract(4),s[1].extract(4),s[2].extract(4),s[3].extract(4),s[4].extract(4),s[5].extract(4),s[6].extract(4),s[7].extract(4), ),
i32x8::new(s[0].extract(5),s[1].extract(5),s[2].extract(5),s[3].extract(5),s[4].extract(5),s[5].extract(5),s[6].extract(5),s[7].extract(5), ),
i32x8::new(s[0].extract(6),s[1].extract(6),s[2].extract(6),s[3].extract(6),s[4].extract(6),s[5].extract(6),s[6].extract(6),s[7].extract(6), ),
i32x8::new(s[0].extract(7),s[1].extract(7),s[2].extract(7),s[3].extract(7),s[4].extract(7),s[5].extract(7),s[6].extract(7),s[7].extract(7), ),
];

该宏应该能够为不同的矩阵大小(4或8)生成代码。

我尝试了几种不同的方法,但是我从未设法使宏重复n次n项模式。

对我而言,最合乎逻辑的是:

macro_rules! square {
(($($x:tt),*), ($($y:tt),*)) => {
[
$([
$( s[$x].extract($y) ),*
]),*
]
};
($($x:expr),*) => { square!( ($($x),*) , ($($x),*) ) };
}

但是失败了
error: attempted to repeat an expression containing no syntax variables matched as repeating at this depth

最佳答案

您可以做到,但是您将需要通过递归来处理外部重复:

macro_rules! square {
(@row [$($acc:expr),*] [$($before:expr),*] $current:expr $(, $after:expr)*) => {
square!(@row
[ $($acc,)*
stringify!($(s[$current].extract ($before),)*
s[$current].extract ($current)
$(, s[$current].extract ($after))*) ]
[ $($before,)* $current ]
$($after),*)
};
(@row [$($acc:tt)*] [$($before:expr),*]) => { vec![ $($acc)* ] };
($($r:expr),*) => {
square!(@row [] [] $($r),*)
};
}


Playground

我将其称为 stringify!,以便该代码可以在没有依赖项的情况下在操场上进行编译。您将需要替换它们以满足您的需要(可能只是删除 stringify!调用,并使用传递给宏的标识符替换 s)。

累积 $acc中的值并在递归结束时立即将其全部输出的想法称为 push-down accumulation pattern。如果您不熟悉此概念,请在 little book of Rust macros中对其进行详细说明。

关于matrix - 是否可以编写一个可以转置矩阵的rust宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61251075/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com