Expected stride to be a single integer value or a list of 1 values to match the convolution dimensions, but got stride=[1, 1]
I read this question but it doesnt seem to answer my question :(.

So basically I'm trying to vectorize the game snake so it can run faster.
Here is my code till now:

import torch
import torch.nn.functional as F
device = torch.device("cpu")
class SnakeBoard:
  def __init__(self, board=None):
    if board != None:
      self.channels = board
    else:
      # 0 - Food, 1 - Head, 2 - Body
      self.channels = torch.zeros(1, 3, 15, 17,
                                  device=device)

      # Initialize game channels
      self.channels[:, 0, 7, 12] = 1
      self.channels[:, 1, 7, 5] = 1
      self.channels[:, 2, 7, 2:6] = torch.arange(1, 5)
    self.move()

  def move(self):
    self.channels[:, 2] -= 1
    F.relu(self.channels[:, 2], inplace=True)
    # Up movement test
    F.conv2d(self.channels[:, 1], torch.tensor([[[0,1,0],[0,0,0],[0,0,0]]]), padding=1)

SnakeBoard()


The first dimension in channels represents batch size, second dimension represent the 3 channels of the snake game: food, head, and body, and finally the third and fourth dimensions represent the height and width of the board.

Unfortunately when running the code I get error: Expected stride to be a single integer value or a list of 1 values to match the convolution dimensions, but got stride=[1, 1]

How can I fix that?

The dimensions of the inputs for the convolution are not correct for a 2D convolution. Let's have a look at the dimensions you're passing to F.conv2d:

self.channels[:, 1].size()
# =&gt; torch.Size([1, 15, 17])
torch.tensor([[[0,1,0],[0,0,0],[0,0,0]]]).size()
# =&gt; torch.Size([1, 3, 3])


The correct sizes should be


input: (batch_size, in_channels , height, width)
weight: (out_channels, in_channels , kernel_height, kernel_width)


Because your weight has only 3 dimensions, it is considered to be a 1D convolution, but since you called F.conv2d the stride and padding will be tuples and therefore it won't work.

For the input you indexed the second dimension, which selects that particular element across that dimensions and eliminates that dimensions. To keep that dimension you can index it with a slice of just one element.
And for the weight you are missing one dimension as well, which can just be added directly. Also your weight is of type torch.long, since you are only using integers in the tensor creation, but the weight needs to be of type torch.float.

F.conv2d(self.channels[:, 1:2], torch.tensor([[[[0,1,0],[0,0,0],[0,0,0]]]], dtype=torch.float), padding=1)




On a different note, I don't think that convolutions are appropriate for this use case, because you're not using a key property of the convolution, which is to capture the surroundings. Those are just too many unnecessary computations to achieve what you want, most of them are multiplications with 0.

For example, a move up is much easier to achieve by removing the first row and adding a new row of zeros at the end, so everything is shifted up (assuming that the first row is the top and the last row is the bottom of the board).

head = self.channels[:, 1:2]
batch_size, channels, height, width = head.size()
# Take everything but the first row of the head
# Add a row of zeros to the end by concatenating them across the height (dimension 2)
new_head = torch.cat([head[:, :, 1:], torch.zeros(batch_size, channels, 1, width)], dim=2)

# Or if you want to wrap it around the board, it's even simpler.
# Move the first row to the end
wrap_around_head = torch.cat([head[:, :, 1:], head[:, :, 0:1]], dim=2)

