"""
A theano / pylearn2 wrapper for Alex Krizhevsky's cuda-convnet
software.
"""
__authors__ = "Ian Goodfellow"
__copyright__ = "Copyright 2010-2012, Universite de Montreal"
__credits__ = ["Ian Goodfellow"]
__license__ = "3-clause BSD"
__maintainer__ = "LISA Lab"
__email__ = "pylearn-dev@googlegroups"

"""
This module contains code copied directly or modified from cuda-convnet.
The copyright and licensing notice for this code is reproduced below:


/*
 * Copyright (c) 2011, Alex Krizhevsky (akrizhevsky@gmail.com)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

"""
import warnings

from theano.sandbox import cuda
from theano import config


def check_cuda(feature_name="You are using code that relies on cuda-convnet. Cuda-convnet",
               check_enabled=True):
    """
    Call this function before sections of code that depend on the cuda_convnet module.
    It will raise a RuntimeError if the GPU is not available.

    feature_name: The name of the feature the user should be told is unavailable.
    """
    if not cuda.cuda_available:
        raise RuntimeError("%s only runs on GPUs, but there doesn't "
                "seem to be a GPU available. If you would like assistance making "
                "a CPU version of convolutional maxout, contact "
                "pylearn-dev@googlegroups.com." % feature_name)

    if not hasattr(cuda.cuda_ndarray.cuda_ndarray, 'cublas_v2'):
        warnings.warn(
            "You are using probably a too old Theano version. That"
            " will cause compilation crash. If so, update Theano.")
    elif not cuda.cuda_ndarray.cuda_ndarray.cublas_v2():
        raise RuntimeError("You are using probably a too old Theano version."
                           " That will cause compilation crash. Update Theano")

    if check_enabled and not cuda.cuda_enabled:
        raise RuntimeError("%s must run be with theano configured to use the GPU" % feature_name)
