import torch


def get_meshgrid_samples(lower, upper, mesh_size: tuple, dtype) ->\
        torch.Tensor:
    """
    Often we want to get the mesh samples in a box lower <= x <= upper.
    This returns a torch tensor of size (prod(mesh_size), sample_dim), where
    each row is a sample in the meshgrid.
    """
    sample_dim = len(mesh_size)
    assert (len(upper) == sample_dim)
    assert (len(lower) == sample_dim)
    assert (len(mesh_size) == sample_dim)
    meshes = []
    for i in range(sample_dim):
        meshes.append(
            torch.linspace(lower[i], upper[i], mesh_size[i], dtype=dtype))
    mesh_tensors = torch.meshgrid(*meshes)
    return torch.cat(
        [mesh_tensors[i].reshape((-1, 1)) for i in range(sample_dim)], dim=1)