nnaisense / evotorch

Advanced evolutionary computation library built directly on top of PyTorch, created at NNAISENSE.
https://evotorch.ai
Apache License 2.0
997 stars 62 forks source link

CMAES "can't convert cuda:0 device type tensor to numpy" error #61

Closed machaneus closed 1 year ago

machaneus commented 1 year ago

Hi guys,

Your work is awesome! 🏆

I am running into the following error when trying to run your example script with CMAES instead of SNES.

TypeError: can't convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.

Here's the script:

#CMA-ES Test
from evotorch import Problem
from evotorch.algorithms import SNES, CMAES
from evotorch.logging import StdOutLogger, PandasLogger
import math
import matplotlib.pyplot as plt
import torch

# Declare the objective function
def rastrigin(x: torch.Tensor) -> torch.Tensor:
    A = 10
    (_, n) = x.shape
    return A * n + torch.sum((x**2) - A * torch.cos(2 * math.pi * x), 1)

# Declare the problem
problem = Problem(
    "min",
    rastrigin,
    initial_bounds=(-5.12, 5.12),
    solution_length=100,
    vectorized=True,
    device="cuda:0"  # enable this line if you wish to use GPU
)

# Initialize the SNES algorithm to solve the problem
searcher = CMAES(problem, popsize=2000, stdev_init=10.0)

# Initialize a standard output logger, and a pandas logger
#_ = StdOutLogger(searcher, interval=10)
pandas_logger = PandasLogger(searcher)
searcher.run(5000)

Any help would be appreciated!

Best,

NaturalGradient commented 1 year ago

Hi @machaneus . Sorry to hear you've run into this issue! Before we go into detail, could you please confirm which version of EvoTorch you are using? In previous versions (<= 0.3), the CMA-ES algorithm was actually an API wrapper for the pycma library, and therefore did not support computations on CUDA devices. Since 0.4.0, we've added our own version of CMA-ES which should hopefully be a 1:1 match to pycma but is fully vectorised and runs on accelerated devices. Hopefully your issue can just be resolved by upgrading evotorch to 0.4.0. If this is not the cause of the problem, please let me know and I'll dive into this issue further. On my end, your example code runs without the error you reported when using evotorch 0.4.0.

machaneus commented 1 year ago

Hi @NaturalGradient,

Thanks a lot for your reply!

I am experimenting with evotorch in a Colab environment. I am installing evotorch with

%pip install evotorch==0.4.0

And then run the code I posted above in a cell. The error persists.

I wonder if it's a Colab issue after all...

NaturalGradient commented 1 year ago

Hi @machaneus Sorry, I should have updated you. We did a little digging and it seems there is an issue in 0.4.0 but (due to a mistake on my end) I had tested your code on a local branch where I had already 'accidentally' fixed it by resolving a different issue! I've discussed with @engintoklu and it seems quite easy to fix so a PR should appear here soon. In the mean time, could you try:

searcher = CMAES(problem, popsize=2000, stdev_init=10.0, limit_C_decomposition = False)

The limit_C_decomposition flag is there to ensure O(n^2) time where n is the dimension, but setting it to False completely side-steps the bug it seems. On CUDA you shouldn't really see a notable performance drop anyway, since the matrix factorisation associated with limit_C_decomposition is efficiently computed on the GPU. Obviously if this is for a paper etc. its not ideal to be using a non-standard configuration, so I'll notify you as soon as we have that PR up and as soon as it is included in the next minor release.

Thanks for your feedback and my apologies for the bug!

machaneus commented 1 year ago

Indeed, it works fine with limit_C_decomposition = False

Thanks for replying so promptly!

NaturalGradient commented 1 year ago

Hi @machaneus. If you would like to use the faster limited C decomposition, you can pip install the branch I've created with the fix: https://github.com/nnaisense/evotorch/tree/fix/cmaes-C-cuda

This stack overflow answer will give you guidance on how to install git branches if this is something you haven't done before: https://stackoverflow.com/questions/20101834/pip-install-from-git-repo-branch

Hopefully soon this PR will be merged and we'll release 0.4.1 which will have the fix included.

Thanks!