Skip to content
This repository has been archived by the owner on Aug 3, 2019. It is now read-only.

About Version-5 reshape #13

Open
YUIAZU000 opened this issue Jun 6, 2018 · 4 comments
Open

About Version-5 reshape #13

YUIAZU000 opened this issue Jun 6, 2018 · 4 comments
Assignees

Comments

@YUIAZU000
Copy link

I run onnx-plaidml on my model and got an error:
“Version-5 reshape() is not yet implemented by the PlaidML ONNX backend”
I find it caused by the function pixelshuffle I used. Do you have an incomplete implement of this operation?

@earhart earhart self-assigned this Jun 6, 2018
@earhart
Copy link
Contributor

earhart commented Jun 6, 2018

In Version 1, reshape took the new shape as a list of ints. In Version 5, this was replaced with a one-dimensional input tensor. So when the model is prepared, we can't actually know the shape of anything; we find out when the model is bound to actual inputs.

I've thought a little about how to implement this: since a PlaidML function operates over symbolic-sized tensors anyway (output shapes aren't known until all input shapes have been bound), it might be possible to simply defer reshape computations. Doing this will be tricky; the program compilation cache is currently keyed off tensor sizes, not tensor contents. I think it's doable, but it'll take some time, and it'll have to be scheduled relative to other features we'd like to add.

In the meantime, if anyone feels like working on this, I'd be very happy to review PRs. :-)

@YUIAZU000
Copy link
Author

@earhart I have solved the problem.
`import numpy as np
import plaidml
import plaidml.tile

_ctx = plaidml.Context()
_device = plaidml.Device(_ctx, None)

def get_value(x):
func = plaidml.tile.compose(_ctx, _device, [], [('out', x)])
invoker = plaidml.Invoker(_ctx, func)
shape = invoker.get_output_shape('out')
tensor = plaidml.Tensor(_device, shape)
invoker.set_output('out', tensor)
invoker.invoke()
array = np.ndarray(x.shape.dims, dtype=plaidml.tile.PLAIDML_DTYPE_TO_NUMPY[x.shape.dtype])
with tensor.mmap_current() as view:
view.copy_to_ndarray(array)
return array`

You can use get_value to get the value of shape, and it works on my model.

@jack-willturner
Copy link

Can you give an example of how to use this?

@earhart
Copy link
Contributor

earhart commented Jun 8, 2018

The only problem with this approach is that we still don't have the input tensor data to use for computing the reshape() until after the inputs are bound, after the tensor's been prepared (i.e. compiled).

One other idea might be to defer the compilation: if we figure out that there's an operation whose Tile code depends on a tensor input, we could hold off on doing all the binding until we know the value of that input, and use caching to keep performance reasonable. I think we'd also want to add a check to see which tensors are actually used by the resulting program; if a tensor's only being provided to determine a shape, there's no reason to be transferring its data to the GPU.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants