Re: [eigen] Returning Tensor Expressions
• To: eigen@xxxxxxxxxxxxxxxxxxx
• Subject: Re: [eigen] Returning Tensor Expressions
• From: Eugene Zhulenev <ezhulenev@xxxxxxxxxx>
• Date: Tue, 17 Dec 2019 11:31:08 -0800
• Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=VDIeDCs1GqCqcnVag45ng80E58GovJzNDnq1Ap1afuw=; b=h/HfDNlPMPbzFF9ACKbeGl3dgEXvq7wwrlR5cUw6F4Dy9KDZf5FQaXkfzy6Y5o1VKN FjIkLWbLuLAfjD0q4zIBnVpt0N9cwOqkCdMC31l634wgyy4SJN2NfkFKV8uwas2tbP1p /jX41lGxWhv40hkKS3IRdk9Ef7yGFcfXKunJIiw4NwqlF+OV+/AQeQtu2RoNTgrqWw/9 4+4Vb8Ut7kv+KUI2dV7OT8TGvcyUxUxc5772gVLI2VvFVVc+Gw3DyklsAKhxICHlc/v+ f/o4BI/TMt/RVmAPtsLV7ZLKp3Tds5HzNt0EmvJpnu0XUhcHtXZXFRpdq5H4mde4KYNP 3ROQ==

On Tue, Dec 17, 2019 at 4:15 AM Wood, Tobias <tobias.wood@xxxxxxxxx> wrote:

Hello,

I am trying to write a finite difference function for Eigen::Tensors. Currently I am using a lambda:

auto diff = [](Eigen::Tensor<std::complex<float>, 3> const &a, Eigen::Index const d) {

Dims3 const sz{a.dimension(0) - 2, a.dimension(1) - 2, a.dimension(2) - 2};

Dims3 const st1{1, 1, 1};

Dims3 fwd{1, 1, 1};

Dims3 bck{1, 1, 1};

fwd[d] = 2;

bck[d] = 0;

return (a.slice(fwd, sz) - a.slice(bck, sz)) / a.slice(st1, sz).constant(2.f);

};

This works okay. However, I would like to do two things:

1 – Change this from a lambda into a free function. What should the return type of the function be, so that it returns the _expression_/operation and does not evaluate the tensor into a temporary?

2 – I would prefer to pass in a TensorRef, so I can pass in a .chip() from a 4D tensor without a temporary. When I try to do this with the current lambda, and I am assigning to a slice, e.g.

b.chip<3>(0).slice(st1, sz) = diff(a, 0);

I get the following error:

TensorRef.h:413:51: error: cannot initialize return object of type 'Eigen::TensorEvaluator<const Eigen::TensorRef<Eigen::Tensor<std::__1::complex<float>, 3, 0, long> >, Eigen::ThreadPoolDevice>::Scalar *' (aka 'std::__1::complex<float> *') with an rvalue of type 'const Eigen::TensorRef<Eigen::Tensor<std::__1::complex<float>, 3, 0, long> >::Scalar *' (aka 'const std::__1::complex<float> *')

This appears to be complaining that I can’t assign a `const std::complex<float> *` to a `std::complex<float> *`?

Can you create a minimal repro for this, can't quite figure out how you try to use TensorRef, and what is the source of `const` in the _expression_. Looks like a bug somewhere in typedefs.