Hi,
I am trying to implement a cellular automaton with Nx, but I can’t seem to get past this error.
So I have a tensor of unsigned 8 bit numbers which I want to rotate left, i.e. wrap the leftmost item onto the right.
I define the initial tensor, annotating its type:
def seed() do
Nx.tensor([0, 0, 0, 0, 1, 0, 0, 0, 0], type: {:u, 8})
end
then my rotate function which maybe is not the right way to do this but it should at least compile:
def rotate_left(row) do
rightmost = Nx.slice(row, [Nx.size(row)-1], [1])
drop_leftmost = Nx.tensor(Nx.slice(row, [1], [Nx.size(row)]))
Nx.put_slice(drop_leftmost, [Nx.size(row)-1], rightmost)
end
The error I get:
** (ArgumentError) cannot infer the numerical type of nx.Tensor<
u8[9]
[0, 0, 0, 0, 1, 0, 0, 0, 0](nx 0.1.0) lib/nx/type.ex:110: Nx.Type.infer/2 (nx 0.1.0) lib/nx/type.ex:98: Nx.Type.infer/1 (nx 0.1.0) lib/nx.ex:481: Nx.tensor/2 (mkrandio 0.1.0) lib/mkrandio/core.ex:18: Mkrandio.Core.rotate_left/1
line 18 is the middle line, drop_leftmost = …
First, the error is showing the correct type, and if I try an additional annotation in the call to Nx.tensor like this:
drop_leftmost = Nx.tensor(Nx.slice(row, [1], [Nx.size(row)]), type: {:u, 8})
I get this error:
** (FunctionClauseError) no function clause matching in Nx.tensor/3
The following arguments were given to Nx.tensor/3: # 1 #Nx.Tensor< u8[9] [0, 0, 0, 0, 1, 0, 0, 0, 0] > # 2 {:u, 8} # 3 [type: {:u, 8}] Attempted function clauses (showing 2 out of 2): defp tensor(arg, type, opts) when is_number(arg) defp tensor(arg, type, opts) when is_list(arg)
So it seems it is already receiving the type annotation as an argument, here is where my knowledge of Elixir is being outstripped, I am not sure where that argument is coming from, as I understand slice it just returns a tensor, so my additional annotation is coming in as a third superfluous argument
Can anyone shed light on where I am going wrong?
Thanks