gpt4 book ai didi

c++ - Eigen 中的 "aliasing detected during transposition"

转载 作者:太空宇宙 更新时间:2023-11-04 13:13:43 26 4
gpt4 key购买 nike

我有以下代码:

template <typename T>
using Arr = Array<T, Dynamic, 1>;

template <typename T>
using Arr2 = Array<T, Dynamic, Dynamic>;

template <typename T>
Arr2<typename T::Scalar> reshape (const ArrayBase<T> & A, const uint n, const uint m) {
return Map<const Arr2<typename T::Scalar>>(A.eval().data(), n, m);
}

Arr<double> v = Arr<double>::LinSpaced(16, 0, 15);
auto w = reshape(v, 4, 4).transpose();
std::cout << w << std::endl;

产生错误

static void Eigen::internal::checkTransposeAliasing_impl::run(const Derived&, const OtherDerived&) [with Derived = Eigen::Array; OtherDerived = Eigen::Transpose >; bool MightHaveTransposeAliasing = true]: Assertion `(!check_transpose_aliasing_run_time_selector ::IsTransposed,OtherDerived> ::run(extract_data(dst), other)) && "aliasing detected during transposition, use transposeInPlace() " "or evaluate the rhs into a temporary using .eval()"' failed.

添加eval确实解决了这个问题:

auto w = reshape(v, 4, 4).transpose().eval();

(但添加它作为打印行,因为 << w.eval() << 没有)。

我想更好地了解正在发生的事情,并找出是否有其他方法可以解决此问题。

谢谢

最佳答案

基本上您只能创建现有对象的表达式/引用。当对象超出范围时,表达式/引用无效/未定义。

auto w ,您正在创建临时表达式 Arr2对象,其生命在此行之后结束,使得 w无效的。您看到的断言有助于检查这种情况。此临时对象是在您转换 Map 时创建的反对 Arr2 return 行的对象,这涉及从输入 vector 到临时的不需要的数据复制 Arr2目的。这恰好是 the situations that you should not use auto 之一.如果您愿意再接受一份拷贝,则以下代码将起作用。相当于你加上.eval()在您的原始代码中。

#include <Eigen/Eigen>
#include <iostream>
using namespace Eigen;

template<typename T>
using Arr = Array<T, Dynamic, 1>;
template<typename T>
using Arr2 = Array<T, Dynamic, Dynamic>;

template<typename T>
Arr2<typename T::Scalar> reshape(const ArrayBase<T> & A, const uint n,
const uint m) {
return Map<const Arr2<typename T::Scalar>>(A.eval().data(), n, m);
}

int main() {
Arr<double> v = Arr<double>::LinSpaced(16, 0, 15);
Arr2<double> w = reshape(v, 4, 4).transpose();
std::cout << w << std::endl;
return 0;
}

或者,将返回类型更改为 Map<const Arr2<typename T::Scalar>>是避免上面提到的两个拷贝的更好方法,你仍然可以使用 auto保持w作为一个表达。以下代码是一个更好的工作版本。

#include <Eigen/Eigen>
#include <iostream>
using namespace Eigen;

template<typename T>
using Arr = Array<T, Dynamic, 1>;
template<typename T>
using Arr2 = Array<T, Dynamic, Dynamic>;

template<typename T>
Map<const Arr2<typename T::Scalar>> reshape(const ArrayBase<T> & A,
const uint n, const uint m) {
return Map<const Arr2<typename T::Scalar>>(A.eval().data(), n, m);
}

int main() {
Arr<double> v = Arr<double>::LinSpaced(16, 0, 15);
auto w = reshape(v, 4, 4).transpose();
std::cout << w << std::endl;
return 0;
}

另一方面,我认为你的reshape当 A 是表达式时仍然是错误的,如 A.eval().data()是一个临时对象,其生命在函数调用后结束。你的reshape API 会使不知道此限制的人感到困惑。

实际上创建 reshape 函数是不必要的,因为构建一个 Map对象本身在语义上意味着在连续的内存空间中 reshape 一些数据。我会推荐以下表格。它只比单词“reshape”长一点,不涉及临时缓冲区/数据复制,并且 auto w仍然是一个表达式对象。

#include <Eigen/Eigen>
#include <iostream>
using namespace Eigen;

template<typename T>
using Arr = Array<T, Dynamic, 1>;
template<typename T>
using Arr2 = Array<T, Dynamic, Dynamic>;

int main() {
Arr<double> v = Arr<double>::LinSpaced(16, 0, 15);
auto w = Map<Arr2<double>>(v.data(), 4, 4).transpose();
std::cout << w << std::endl;
return 0;
}

关于c++ - Eigen 中的 "aliasing detected during transposition",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38494624/

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