"""
The :mod:`sklearn.model_selection._search` includes utilities to fine-tune the
parameters of an estimator.
"""
from __future__ import print_function
from __future__ import division
# Author: Alexandre Gramfort<EMAIL_ADDRESS># Gael Varoquaux<EMAIL_ADDRESS># Andreas Mueller<EMAIL_ADDRESS># Olivier Grisel<EMAIL_ADDRESS># Raghav RV<EMAIL_ADDRESS># License: BSD 3 clause
from abc import ABCMeta, abstractmethod
from collections import Mapping, namedtuple, defaultdict, Sequence
from functools import partial, reduce
from itertools import product
import operator
import warnings
import numpy as np
from scipy.stats import rankdata
from ..base import BaseEstimator, is_classifier, clone
from ..base import MetaEstimatorMixin
from ._split import check_cv
from ._validation import _fit_and_score
from ._validation import _aggregate_score_dicts
from ..exceptions import NotFittedError
from ..externals.joblib import Parallel, delayed
from ..externals import six
from ..utils import check_random_state
from ..utils.fixes import sp_version
from ..utils.fixes import MaskedArray
from ..utils.random import sample_without_replacement
from ..utils.validation import indexable, check_is_fitted
from ..utils.metaestimators import if_delegate_has_method
from ..metrics.scorer import _check_multimetric_scoring
from ..metrics.scorer import check_scoring
__all__ = ['GridSearchCV', 'ParameterGrid', 'fit_grid_point',
'ParameterSampler', 'RandomizedSearchCV']
class ParameterGrid(object):
"""Grid of parameters with a discrete number of values for each.
Can be used to iterate over parameter value combinations with the
Python built-in function iter.
Read more in the :ref:`User Guide <search>`.
Parameters
----------
param_grid : dict of string to sequence, or sequence of such
The parameter grid to explore, as a dictionary mapping estimator
parameters to sequences of allowed values.
An empty dict signifies default parameters.
A sequence of dicts signifies a sequence of grids to search, and is
useful to avoid exploring parameter combinations that make no sense
or have no effect. See the examples below.
Examples
--------
>>> from sklearn.model_selection import ParameterGrid
>>> param_grid = {'a': [1, 2], 'b': [True, False]}
>>> list(ParameterGrid(param_grid)) == (
... [{'a': 1, 'b': True}, {'a': 1, 'b': False},
... {'a': 2, 'b': True}, {'a': 2, 'b': False}])
True
>>> grid = [{'kernel': ['linear']}, {'kernel': ['rbf'], 'gamma': [1, 10]}]
>>> list(ParameterGrid(grid)) == [{'kernel': 'linear'},
... {'kernel': 'rbf', 'gamma': 1},
... {'kernel': 'rbf', 'gamma': 10}]
True
>>> ParameterGrid(grid)[1] == {'kernel': 'rbf', 'gamma': 1}
True
See also
--------
:class:`GridSearchCV`:
Uses :class:`ParameterGrid` to perform a full parallelized parameter
search.
"""
def __init__(self, param_grid):
if isinstance(param_grid, Mapping):
# wrap dictionary in a singleton list to support either dict
# or list of dicts
param_grid = [param_grid]
self.param_grid = param_grid
def __iter__(self):
"""Iterate over the points in the grid.
Returns
-------
params : iterator over dict of string to any
Yields dictionaries mapping each estimator parameter to one of its
allowed values.
"""
for p in self.param_grid:
# Always sort the keys of a dictionary, for reproducibility
items = sorted(p.items())
if not items:
yield {}
else:
keys, values = zip(*items)
for v in product(*values):
params = dict(zip(keys, v))
yield params
def __len__(self):
"""Number of points on the grid."""
# Product function that can handle iterables (np.product can't).
product = partial(reduce, operator.mul)
return sum(product(len(v) for v in p.values()) if p else 1
for p in self.param_grid)
def __getitem__(self, ind):
"""Get the parameters that would be ``ind``th in iteration
Parameters
----------
ind : int
The iteration index
Returns
-------
params : dict of string to any
Equal to list(self)[ind]
"""
# This is used to make discrete sampling without replacement memory
# efficient.
for sub_grid in self.param_grid:
# XXX: could memoize information used here
if not sub_grid:
if ind == 0:
return {}
else:
ind -= 1
continue
# Reverse so most frequent cycling parameter comes first
keys, values_lists = zip(*sorted(sub_grid.items())[::-1])
sizes = [len(v_list) for v_list in values_lists]
total = np.product(sizes)
if ind >= total:
# Try the next grid
ind -= total
else:
out = {}
for key, v_list, n in zip(keys, values_lists, sizes):
ind, offset = divmod(ind, n)
out[key] = v_list[offset]
return out
raise IndexError('ParameterGrid index out of range')
class ParameterSampler(object):
"""Generator on parameters sampled from given distributions.
Non-deterministic iterable over random candidate combinations for hyper-
parameter search. If all parameters are presented as a list,
sampling without replacement is performed. If at least one parameter
is given as a distribution, sampling with replacement is used.
It is highly recommended to use continuous distributions for continuous
parameters.
Note that before SciPy 0.16, the ``scipy.stats.distributions`` do not
accept a custom RNG instance and always use the singleton RNG from
``numpy.random``. Hence setting ``random_state`` will not guarantee a
deterministic iteration whenever ``scipy.stats`` distributions are used to
define the parameter search space. Deterministic behavior is however
guaranteed from SciPy 0.16 onwards.
Read more in the :ref:`User Guide <search>`.
Parameters
----------
param_distributions : dict
Dictionary where the keys are parameters and values
are distributions from which a parameter is to be sampled.
Distributions either have to provide a ``rvs`` function
to sample from them, or can be given as a list of values,
where a uniform distribution is assumed.
n_iter : integer
Number of parameter settings that are produced.
random_state : int, RandomState instance or None, optional (default=None)
Pseudo random number generator state used for random uniform sampling
from lists of possible values instead of scipy.stats distributions.
If int, random_state is the seed used by the random number generator;
If RandomState instance, random_state is the random number generator;
If None, the random number generator is the RandomState instance used
by `np.random`.
Returns
-------
params : dict of string to any
**Yields** dictionaries mapping each estimator parameter to
as sampled value.
Examples
--------
>>> from sklearn.model_selection import ParameterSampler
>>> from scipy.stats.distributions import expon
>>> import numpy as np
>>> np.random.seed(0)
>>> param_grid = {'a':[1, 2], 'b': expon()}
>>> param_list = list(ParameterSampler(param_grid, n_iter=4))
>>> rounded_list = [dict((k, round(v, 6)) for (k, v) in d.items())
... for d in param_list]
>>> rounded_list == [{'b': 0.89856, 'a': 1},
... {'b': 0.923223, 'a': 1},
... {'b': 1.878964, 'a': 2},
... {'b': 1.038159, 'a': 2}]
True
"""
def __init__(self, param_distributions, n_iter, random_state=None):
self.param_distributions = param_distributions
self.n_iter = n_iter
self.random_state = random_state
def __iter__(self):
# check if all distributions are given as lists
# in this case we want to sample without replacement
all_lists = np.all([not hasattr(v, "rvs")
for v in self.param_distributions.values()])
rnd = check_random_state(self.random_state)
if all_lists:
# look up sampled parameter settings in parameter grid
param_grid = ParameterGrid(self.param_distributions)
grid_size = len(param_grid)
if grid_size < self.n_iter:
raise ValueError(
"The total space of parameters %d is smaller "
"than n_iter=%d. For exhaustive searches, use "
"GridSearchCV." % (grid_size, self.n_iter))
for i in sample_without_replacement(grid_size, self.n_iter,
random_state=rnd):
yield param_grid[i]
else:
# Always sort the keys of a dictionary, for reproducibility
items = sorted(self.param_distributions.items())
for _ in six.moves.range(self.n_iter):
params = dict()
for k, v in items:
if hasattr(v, "rvs"):
if sp_version < (0, 16):
params[k] = v.rvs()
else:
params[k] = v.rvs(random_state=rnd)
else:
params[k] = v[rnd.randint(len(v))]
yield params
def __len__(self):
"""Number of points that will be sampled."""
return self.n_iter
def fit_grid_point(X, y, estimator, parameters, train, test, scorer,
verbose, error_score='raise', **fit_params):
"""Run fit on one set of parameters.
Parameters
----------
X : array-like, sparse matrix or list
Input data.
y : array-like or None
Targets for input data.
estimator : estimator object
A object of that type is instantiated for each grid point.
This is assumed to implement the scikit-learn estimator interface.
Either estimator needs to provide a ``score`` function,
or ``scoring`` must be passed.
parameters : dict
Parameters to be set on estimator for this grid point.
train : ndarray, dtype int or bool
Boolean mask or indices for training set.
test : ndarray, dtype int or bool
Boolean mask or indices for test set.
scorer : callable or None
The scorer callable object / function must have its signature as
``scorer(estimator, X, y)``.
If ``None`` the estimator's default scorer is used.
verbose : int
Verbosity level.
**fit_params : kwargs
Additional parameter passed to the fit function of the estimator.
error_score : 'raise' (default) or numeric
Value to assign to the score if an error occurs in estimator fitting.
If set to 'raise', the error is raised. If a numeric value is given,
FitFailedWarning is raised. This parameter does not affect the refit
step, which will always raise the error.
Returns
-------
score : float
Score of this parameter setting on given training / test split.
parameters : dict
The parameters that have been evaluated.
n_samples_test : int
Number of test samples in this split.
"""
# NOTE we are not using the return value as the scorer by itself should be
# validated before. We use check_scoring only to reject multimetric scorer
check_scoring(estimator, scorer)
scores, n_samples_test = _fit_and_score(estimator, X, y,
scorer, train,
test, verbose, parameters,
fit_params=fit_params,
return_n_test_samples=True,
error_score=error_score)
return scores, parameters, n_samples_test
def _check_param_grid(param_grid):
if hasattr(param_grid, 'items'):
param_grid = [param_grid]
for p in param_grid:
for name, v in p.items():
if isinstance(v, np.ndarray) and v.ndim > 1:
raise ValueError("Parameter array should be one-dimensional.")
if (isinstance(v, six.string_types) or
not isinstance(v, (np.ndarray, Sequence))):
raise ValueError("Parameter values for parameter ({0}) need "
"to be a sequence(but not a string) or"
" np.ndarray.".format(name))
if len(v) == 0:
raise ValueError("Parameter values for parameter ({0}) need "
"to be a non-empty sequence.".format(name))
# XXX Remove in 0.20
class _CVScoreTuple (namedtuple('_CVScoreTuple',
('parameters',
'mean_validation_score',
'cv_validation_scores'))):
# A raw namedtuple is very memory efficient as it packs the attributes
# in a struct to get rid of the __dict__ of attributes in particular it
# does not copy the string for the keys on each instance.
# By deriving a namedtuple class just to introduce the __repr__ method we
# would also reintroduce the __dict__ on the instance. By telling the
# Python interpreter that this subclass uses static __slots__ instead of
# dynamic attributes. Furthermore we don't need any additional slot in the
# subclass so we set __slots__ to the empty tuple.
__slots__ = ()
def __repr__(self):
"""Simple custom repr to summarize the main info"""
return "mean: {0:.5f}, std: {1:.5f}, params: {2}".format(
self.mean_validation_score,
np.std(self.cv_validation_scores),
self.parameters)
class BaseSearchCV(six.with_metaclass(ABCMeta, BaseEstimator,
MetaEstimatorMixin)):
"""Base class for hyper parameter search with cross-validation."""
@abstractmethod
def __init__(self, estimator, scoring=None,
fit_params=None, n_jobs=1, iid=True,
refit=True, cv=None, verbose=0, pre_dispatch='2*n_jobs',
error_score='raise', return_train_score=True):
self.scoring = scoring
self.estimator = estimator
self.n_jobs = n_jobs
self.fit_params = fit_params
self.iid = iid
self.refit = refit
self.cv = cv
self.verbose = verbose
self.pre_dispatch = pre_dispatch
self.error_score = error_score
self.return_train_score = return_train_score
@property
def _estimator_type(self):
return self.estimator._estimator_type
def score(self, X, y=None):
"""Returns the score on the given data, if the estimator has been refit.
This uses the score defined by ``scoring`` where provided, and the
``best_estimator_.score`` method otherwise.
Parameters
----------
X : array-like, shape = [n_samples, n_features]
Input data, where n_samples is the number of samples and
n_features is the number of features.
y : array-like, shape = [n_samples] or [n_samples, n_output], optional
Target relative to X for classification or regression;
None for unsupervised learning.
Returns
-------
score : float
"""
self._check_is_fitted('score')
if self.scorer_ is None:
raise ValueError("No score function explicitly defined, "
"and the estimator doesn't provide one %s"
% self.best_estimator_)
score = self.scorer_[self.refit] if self.multimetric_ else self.scorer_
return score(self.best_estimator_, X, y)
def _check_is_fitted(self, method_name):
if not self.refit:
raise NotFittedError('This %s instance was initialized '
'with refit=False. %s is '
'available only after refitting on the best '
'parameters. You can refit an estimator '
'manually using the ``best_parameters_`` '
'attribute'
% (type(self).__name__, method_name))
else:
check_is_fitted(self, 'best_estimator_')
@if_delegate_has_method(delegate=('best_estimator_', 'estimator'))
def predict(self, X):
"""Call predict on the estimator with the best found parameters.
Only available if ``refit=True`` and the underlying estimator supports
``predict``.
Parameters
-----------
X : indexable, length n_samples
Must fulfill the input assumptions of the
underlying estimator.
"""
self._check_is_fitted('predict')
return self.best_estimator_.predict(X)
@if_delegate_has_method(delegate=('best_estimator_', 'estimator'))
def predict_proba(self, X):
"""Call predict_proba on the estimator with the best found parameters.
Only available if ``refit=True`` and the underlying estimator supports
``predict_proba``.
Parameters
-----------
X : indexable, length n_samples
Must fulfill the input assumptions of the
underlying estimator.
"""
self._check_is_fitted('predict_proba')
return self.best_estimator_.predict_proba(X)
@if_delegate_has_method(delegate=('best_estimator_', 'estimator'))
def predict_log_proba(self, X):
"""Call predict_log_proba on the estimator with the best found parameters.
Only available if ``refit=True`` and the underlying estimator supports
``predict_log_proba``.
Parameters
-----------
X : indexable, length n_samples
Must fulfill the input assumptions of the
underlying estimator.
"""
self._check_is_fitted('predict_log_proba')
return self.best_estimator_.predict_log_proba(X)
@if_delegate_has_method(delegate=('best_estimator_', 'estimator'))
def decision_function(self, X):
"""Call decision_function on the estimator with the best found parameters.
Only available if ``refit=True`` and the underlying estimator supports
``decision_function``.
Parameters
-----------
X : indexable, length n_samples
Must fulfill the input assumptions of the
underlying estimator.
"""
self._check_is_fitted('decision_function')
return self.best_estimator_.decision_function(X)
@if_delegate_has_method(delegate=('best_estimator_', 'estimator'))
def transform(self, X):
"""Call transform on the estimator with the best found parameters.
Only available if the underlying estimator supports ``transform`` and
``refit=True``.
Parameters
-----------
X : indexable, length n_samples
Must fulfill the input assumptions of the
underlying estimator.
"""
self._check_is_fitted('transform')
return self.best_estimator_.transform(X)
@if_delegate_has_method(delegate=('best_estimator_', 'estimator'))
def inverse_transform(self, Xt):
"""Call inverse_transform on the estimator with the best found params.
Only available if the underlying estimator implements
``inverse_transform`` and ``refit=True``.
Parameters
-----------
Xt : indexable, length n_samples
Must fulfill the input assumptions of the
underlying estimator.
"""
self._check_is_fitted('inverse_transform')
return self.best_estimator_.inverse_transform(Xt)
@property
def classes_(self):
self._check_is_fitted("classes_")
return self.best_estimator_.classes_
def fit(self, X, y=None, groups=None, **fit_params):
"""Run fit with all sets of parameters.
Parameters
----------
X : array-like, shape = [n_samples, n_features]
Training vector, where n_samples is the number of samples and
n_features is the number of features.
y : array-like, shape = [n_samples] or [n_samples, n_output], optional
Target relative to X for classification or regression;
None for unsupervised learning.
groups : array-like, with shape (n_samples,), optional
Group labels for the samples used while splitting the dataset into
train/test set.
**fit_params : dict of string -> object
Parameters passed to the ``fit`` method of the estimator
"""
if self.fit_params is not None:
warnings.warn('"fit_params" as a constructor argument was '
'deprecated in version 0.19 and will be removed '
'in version 0.21. Pass fit parameters to the '
'"fit" method instead.', DeprecationWarning)
if fit_params:
warnings.warn('Ignoring fit_params passed as a constructor '
'argument in favor of keyword arguments to '
'the "fit" method.', RuntimeWarning)
else:
fit_params = self.fit_params
estimator = self.estimator
cv = check_cv(self.cv, y, classifier=is_classifier(estimator))
scorers, self.multimetric_ = _check_multimetric_scoring(
self.estimator, scoring=self.scoring)
if self.multimetric_:
if self.refit is not False and (
not isinstance(self.refit, six.string_types) or
# This will work for both dict / list (tuple)
self.refit not in scorers):
raise ValueError("For multi-metric scoring, the parameter "
"refit must be set to a scorer key "
"to refit an estimator with the best "
"parameter setting on the whole data and "
"make the best_* attributes "
"available for that metric. If this is not "
"needed, refit should be set to False "
"explicitly. %r was passed." % self.refit)
else:
refit_metric = self.refit
else:
refit_metric = 'score'
X, y, groups = indexable(X, y, groups)
n_splits = cv.get_n_splits(X, y, groups)
# Regenerate parameter iterable for each fit
candidate_params = list(self._get_param_iterator())
n_candidates = len(candidate_params)
if self.verbose > 0:
print("Fitting {0} folds for each of {1} candidates, totalling"
" {2} fits".format(n_splits, n_candidates,
n_candidates * n_splits))
base_estimator = clone(self.estimator)
pre_dispatch = self.pre_dispatch
out = Parallel(
n_jobs=self.n_jobs, verbose=self.verbose,
pre_dispatch=pre_dispatch
)(delayed(_fit_and_score)(clone(base_estimator), X, y, scorers, train,
test, self.verbose, parameters,
fit_params=fit_params,
return_train_score=self.return_train_score,
return_n_test_samples=True,
return_times=True, return_parameters=False,
error_score=self.error_score)
for parameters, (train, test) in product(candidate_params,
cv.split(X, y, groups)))
# if one choose to see train score, "out" will contain train score info
if self.return_train_score:
(train_score_dicts, test_score_dicts, test_sample_counts, fit_time,
score_time) = zip(*out)
else:
(test_score_dicts, test_sample_counts, fit_time,
score_time) = zip(*out)
# test_score_dicts and train_score dicts are lists of dictionaries and
# we make them into dict of lists
test_scores = _aggregate_score_dicts(test_score_dicts)
if self.return_train_score:
train_scores = _aggregate_score_dicts(train_score_dicts)
results = dict()
def _store(key_name, array, weights=None, splits=False, rank=False):
"""A small helper to store the scores/times to the cv_results_"""
# When iterated first by splits, then by parameters
# We want `array` to have `n_candidates` rows and `n_splits` cols.
array = np.array(array, dtype=np.float64).reshape(n_candidates,
n_splits)
if splits:
for split_i in range(n_splits):
# Uses closure to alter the results
results["split%d_%s"
% (split_i, key_name)] = array[:, split_i]
array_means = np.average(array, axis=1, weights=weights)
results['mean_%s' % key_name] = array_means
# Weighted std is not directly available in numpy
array_stds = np.sqrt(np.average((array -
array_means[:, np.newaxis]) ** 2,
axis=1, weights=weights))
results['std_%s' % key_name] = array_stds
if rank:
results["rank_%s" % key_name] = np.asarray(
rankdata(-array_means, method='min'), dtype=np.int32)
_store('fit_time', fit_time)
_store('score_time', score_time)
# Use one MaskedArray and mask all the places where the param is not
# applicable for that candidate. Use defaultdict as each candidate may
# not contain all the params
param_results = defaultdict(partial(MaskedArray,
np.empty(n_candidates,),
mask=True,
dtype=object))
for cand_i, params in enumerate(candidate_params):
for name, value in params.items():
# An all masked empty array gets created for the key
# `"param_%s" % name` at the first occurence of `name`.
# Setting the value at an index also unmasks that index
param_results["param_%s" % name][cand_i] = value
results.update(param_results)
# Store a list of param dicts at the key 'params'
results['params'] = candidate_params
# NOTE test_sample counts (weights) remain the same for all candidates
test_sample_counts = np.array(test_sample_counts[:n_splits],
dtype=np.int)
for scorer_name in scorers.keys():
# Computed the (weighted) mean and std for test scores alone
_store('test_%s' % scorer_name, test_scores[scorer_name],
splits=True, rank=True,
weights=test_sample_counts if self.iid else None)
if self.return_train_score:
_store('train_%s' % scorer_name, train_scores[scorer_name],
splits=True)
# For multi-metric evaluation, store the best_index_, best_params_ and
# best_score_ iff refit is one of the scorer names
# In single metric evaluation, refit_metric is "score"
if self.refit or not self.multimetric_:
self.best_index_ = results["rank_test_%s" % refit_metric].argmin()
self.best_params_ = candidate_params[self.best_index_]
self.best_score_ = results["mean_test_%s" % refit_metric][
self.best_index_]
if self.refit:
self.best_estimator_ = clone(base_estimator).set_params(
**self.best_params_)
if y is not None:
self.best_estimator_.fit(X, y, **fit_params)
else:
self.best_estimator_.fit(X, **fit_params)
# Store the only scorer not as a dict for single metric evaluation
self.scorer_ = scorers if self.multimetric_ else scorers['score']
self.cv_results_ = results
self.n_splits_ = n_splits
return self
@property
def grid_scores_(self):
check_is_fitted(self, 'cv_results_')
if self.multimetric_:
raise AttributeError("grid_scores_ attribute is not available for"
" multi-metric evaluation.")
warnings.warn(
"The grid_scores_ attribute was deprecated in version 0.18"
" in favor of the more elaborate cv_results_ attribute."
" The grid_scores_ attribute will not be available from 0.20",
DeprecationWarning)
grid_scores = list()
for i, (params, mean, std) in enumerate(zip(
self.cv_results_['params'],
self.cv_results_['mean_test_score'],
self.cv_results_['std_test_score'])):
scores = np.array(list(self.cv_results_['split%d_test_score'
% s][i]
for s in range(self.n_splits_)),
dtype=np.float64)
grid_scores.append(_CVScoreTuple(params, mean, scores))
return grid_scores
class GridSearchCV(BaseSearchCV):
"""Exhaustive search over specified parameter values for an estimator.
Important members are fit, predict.
GridSearchCV implements a "fit" and a "score" method.
It also implements "predict", "predict_proba", "decision_function",
"transform" and "inverse_transform" if they are implemented in the
estimator used.
The parameters of the estimator used to apply these methods are optimized
by cross-validated grid-search over a parameter grid.
Read more in the :ref:`User Guide <grid_search>`.
Parameters
----------
estimator : estimator object.
This is assumed to implement the scikit-learn estimator interface.
Either estimator needs to provide a ``score`` function,
or ``scoring`` must be passed.
param_grid : dict or list of dictionaries
Dictionary with parameters names (string) as keys and lists of
parameter settings to try as values, or a list of such
dictionaries, in which case the grids spanned by each dictionary
in the list are explored. This enables searching over any sequence
of parameter settings.
scoring : string, callable, list/tuple, dict or None, default: None
A single string (see :ref:`scoring_parameter`) or a callable
(see :ref:`scoring`) to evaluate the predictions on the test set.
For evaluating multiple metrics, either give a list of (unique) strings
or a dict with names as keys and callables as values.
NOTE that when using custom scorers, each scorer should return a single
value. Metric functions returning a list/array of values can be wrapped
into multiple scorers that return one value each.
See :ref:`multimetric_grid_search` for an example.
If None, the estimator's default scorer (if available) is used.
fit_params : dict, optional
Parameters to pass to the fit method.
.. deprecated:: 0.19
``fit_params`` as a constructor argument was deprecated in version
0.19 and will be removed in version 0.21. Pass fit parameters to
the ``fit`` method instead.
n_jobs : int, default=1
Number of jobs to run in parallel.
pre_dispatch : int, or string, optional
Controls the number of jobs that get dispatched during parallel
execution. Reducing this number can be useful to avoid an
explosion of memory consumption when more jobs get dispatched
than CPUs can process. This parameter can be:
- None, in which case all the jobs are immediately
created and spawned. Use this for lightweight and
fast-running jobs, to avoid delays due to on-demand
spawning of the jobs
- An int, giving the exact number of total jobs that are
spawned
- A string, giving an expression as a function of n_jobs,
as in '2*n_jobs'
iid : boolean, default=True
If True, the data is assumed to be identically distributed across
the folds, and the loss minimized is the total loss per sample,
and not the mean loss across the folds.
cv : int, cross-validation generator or an iterable, optional
Determines the cross-validation splitting strategy.
Possible inputs for cv are:
- None, to use the default 3-fold cross validation,
- integer, to specify the number of folds in a `(Stratified)KFold`,
- An object to be used as a cross-validation generator.
- An iterable yielding train, test splits.
For integer/None inputs, if the estimator is a classifier and ``y`` is
either binary or multiclass, :class:`StratifiedKFold` is used. In all
other cases, :class:`KFold` is used.
Refer :ref:`User Guide <cross_validation>` for the various
cross-validation strategies that can be used here.
refit : boolean, or string, default=True
Refit an estimator using the best found parameters on the whole
dataset.
For multiple metric evaluation, this needs to be a string denoting the
scorer is used to find the best parameters for refitting the estimator
at the end.
The refitted estimator is made available at the ``best_estimator_``
attribute and permits using ``predict`` directly on this
``GridSearchCV`` instance.
Also for multiple metric evaluation, the attributes ``best_index_``,
``best_score_`` and ``best_parameters_`` will only be available if
``refit`` is set and all of them will be determined w.r.t this specific
scorer.
See ``scoring`` parameter to know more about multiple metric
evaluation.
verbose : integer
Controls the verbosity: the higher, the more messages.
error_score : 'raise' (default) or numeric
Value to assign to the score if an error occurs in estimator fitting.
If set to 'raise', the error is raised. If a numeric value is given,
FitFailedWarning is raised. This parameter does not affect the refit
step, which will always raise the error.
return_train_score : boolean, default=True
If ``'False'``, the ``cv_results_`` attribute will not include training
scores.
Examples
--------
>>> from sklearn import svm, datasets
>>> from sklearn.model_selection import GridSearchCV
>>> iris = datasets.load_iris()
>>> parameters = {'kernel':('linear', 'rbf'), 'C':[1, 10]}
>>> svc = svm.SVC()
>>> clf = GridSearchCV(svc, parameters)
>>> clf.fit(iris.data, iris.target)
... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
GridSearchCV(cv=None, error_score=...,
estimator=SVC(C=1.0, cache_size=..., class_weight=..., coef0=...,
decision_function_shape='ovr', degree=..., gamma=...,
kernel='rbf', max_iter=-1, probability=False,
random_state=None, shrinking=True, tol=...,
verbose=False),
fit_params=None, iid=..., n_jobs=1,
param_grid=..., pre_dispatch=..., refit=..., return_train_score=...,
scoring=..., verbose=...)
>>> sorted(clf.cv_results_.keys())
... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
['mean_fit_time', 'mean_score_time', 'mean_test_score',...
'mean_train_score', 'param_C', 'param_kernel', 'params',...
'rank_test_score', 'split0_test_score',...
'split0_train_score', 'split1_test_score', 'split1_train_score',...
'split2_test_score', 'split2_train_score',...
'std_fit_time', 'std_score_time', 'std_test_score', 'std_train_score'...]
Attributes
----------
cv_results_ : dict of numpy (masked) ndarrays
A dict with keys as column headers and values as columns, that can be
imported into a pandas ``DataFrame``.
For instance the below given table
+------------+-----------+------------+-----------------+---+---------+
|param_kernel|param_gamma|param_degree|split0_test_score|...|rank_t...|
+============+===========+============+=================+===+=========+
| 'poly' | -- | 2 | 0.8 |...| 2 |
+------------+-----------+------------+-----------------+---+---------+
| 'poly' | -- | 3 | 0.7 |...| 4 |
+------------+-----------+------------+-----------------+---+---------+
| 'rbf' | 0.1 | -- | 0.8 |...| 3 |
+------------+-----------+------------+-----------------+---+---------+
| 'rbf' | 0.2 | -- | 0.9 |...| 1 |
+------------+-----------+------------+-----------------+---+---------+
will be represented by a ``cv_results_`` dict of::
{
'param_kernel': masked_array(data = ['poly', 'poly', 'rbf', 'rbf'],
mask = [False False False False]...)
'param_gamma': masked_array(data = [-- -- 0.1 0.2],
mask = [ True True False False]...),
'param_degree': masked_array(data = [2.0 3.0 -- --],
mask = [False False True True]...),
'split0_test_score' : [0.8, 0.7, 0.8, 0.9],
'split1_test_score' : [0.82, 0.5, 0.7, 0.78],
'mean_test_score' : [0.81, 0.60, 0.75, 0.82],
'std_test_score' : [0.02, 0.01, 0.03, 0.03],
'rank_test_score' : [2, 4, 3, 1],
'split0_train_score' : [0.8, 0.9, 0.7],
'split1_train_score' : [0.82, 0.5, 0.7],
'mean_train_score' : [0.81, 0.7, 0.7],
'std_train_score' : [0.03, 0.03, 0.04],
'mean_fit_time' : [0.73, 0.63, 0.43, 0.49],
'std_fit_time' : [0.01, 0.02, 0.01, 0.01],
'mean_score_time' : [0.007, 0.06, 0.04, 0.04],
'std_score_time' : [0.001, 0.002, 0.003, 0.005],
'params' : [{'kernel': 'poly', 'degree': 2}, ...],
}
NOTE
The key ``'params'`` is used to store a list of parameter
settings dicts for all the parameter candidates.
The ``mean_fit_time``, ``std_fit_time``, ``mean_score_time`` and
``std_score_time`` are all in seconds.
For multi-metric evaluation, the scores for all the scorers are
available in the ``cv_results_`` dict at the keys ending with that
scorer's name (``'_<scorer_name>'``) instead of ``'_score'`` shown
above. ('split0_test_precision', 'mean_train_precision' etc.)
best_estimator_ : estimator or dict
Estimator that was chosen by the search, i.e. estimator
which gave highest score (or smallest loss if specified)
on the left out data. Not available if ``refit=False``.
See ``refit`` parameter for more information on allowed values.
best_score_ : float
Mean cross-validated score of the best_estimator
For multi-metric evaluation, this is present only if ``refit`` is
specified.
best_params_ : dict
Parameter setting that gave the best results on the hold out data.
For multi-metric evaluation, this is present only if ``refit`` is
specified.
best_index_ : int
The index (of the ``cv_results_`` arrays) which corresponds to the best
candidate parameter setting.
The dict at ``search.cv_results_['params'][search.best_index_]`` gives
the parameter setting for the best model, that gives the highest
mean score (``search.best_score_``).
For multi-metric evaluation, this is present only if ``refit`` is
specified.
scorer_ : function or a dict
Scorer function used on the held out data to choose the best
parameters for the model.
For multi-metric evaluation, this attribute holds the validated
``scoring`` dict which maps the scorer key to the scorer callable.
n_splits_ : int
The number of cross-validation splits (folds/iterations).
Notes
------
The parameters selected are those that maximize the score of the left out
data, unless an explicit score is passed in which case it is used instead.
If `n_jobs` was set to a value higher than one, the data is copied for each
point in the grid (and not `n_jobs` times). This is done for efficiency
reasons if individual jobs take very little time, but may raise errors if
the dataset is large and not enough memory is available. A workaround in
this case is to set `pre_dispatch`. Then, the memory is copied only
`pre_dispatch` many times. A reasonable value for `pre_dispatch` is `2 *
n_jobs`.
See Also
---------
:class:`ParameterGrid`:
generates all the combinations of a hyperparameter grid.
:func:`sklearn.model_selection.train_test_split`:
utility function to split the data into a development set usable
for fitting a GridSearchCV instance and an evaluation set for
its final evaluation.
:func:`sklearn.metrics.make_scorer`:
Make a scorer from a performance metric or loss function.
"""
def __init__(self, estimator, param_grid, scoring=None, fit_params=None,
n_jobs=1, iid=True, refit=True, cv=None, verbose=0,
pre_dispatch='2*n_jobs', error_score='raise',
return_train_score=True):
super(GridSearchCV, self).__init__(
estimator=estimator, scoring=scoring, fit_params=fit_params,
n_jobs=n_jobs, iid=iid, refit=refit, cv=cv, verbose=verbose,
pre_dispatch=pre_dispatch, error_score=error_score,
return_train_score=return_train_score)
self.param_grid = param_grid
_check_param_grid(param_grid)
def _get_param_iterator(self):
"""Return ParameterGrid instance for the given param_grid"""
return ParameterGrid(self.param_grid)
class RandomizedSearchCV(BaseSearchCV):
"""Randomized search on hyper parameters.
RandomizedSearchCV implements a "fit" and a "score" method.
It also implements "predict", "predict_proba", "decision_function",
"transform" and "inverse_transform" if they are implemented in the
estimator used.
The parameters of the estimator used to apply these methods are optimized
by cross-validated search over parameter settings.
In contrast to GridSearchCV, not all parameter values are tried out, but
rather a fixed number of parameter settings is sampled from the specified
distributions. The number of parameter settings that are tried is
given by n_iter.
If all parameters are presented as a list,
sampling without replacement is performed. If at least one parameter
is given as a distribution, sampling with replacement is used.
It is highly recommended to use continuous distributions for continuous
parameters.
Read more in the :ref:`User Guide <randomized_parameter_search>`.
Parameters
----------
estimator : estimator object.
A object of that type is instantiated for each grid point.
This is assumed to implement the scikit-learn estimator interface.
Either estimator needs to provide a ``score`` function,
or ``scoring`` must be passed.
param_distributions : dict
Dictionary with parameters names (string) as keys and distributions
or lists of parameters to try. Distributions must provide a ``rvs``
method for sampling (such as those from scipy.stats.distributions).
If a list is given, it is sampled uniformly.
n_iter : int, default=10
Number of parameter settings that are sampled. n_iter trades
off runtime vs quality of the solution.
scoring : string, callable, list/tuple, dict or None, default: None
A single string (see :ref:`scoring_parameter`) or a callable
(see :ref:`scoring`) to evaluate the predictions on the test set.
For evaluating multiple metrics, either give a list of (unique) strings
or a dict with names as keys and callables as values.
NOTE that when using custom scorers, each scorer should return a single
value. Metric functions returning a list/array of values can be wrapped
into multiple scorers that return one value each.
See :ref:`multimetric_grid_search` for an example.
If None, the estimator's default scorer (if available) is used.
fit_params : dict, optional
Parameters to pass to the fit method.
.. deprecated:: 0.19
``fit_params`` as a constructor argument was deprecated in version
0.19 and will be removed in version 0.21. Pass fit parameters to
the ``fit`` method instead.
n_jobs : int, default=1
Number of jobs to run in parallel.
pre_dispatch : int, or string, optional
Controls the number of jobs that get dispatched during parallel
execution. Reducing this number can be useful to avoid an
explosion of memory consumption when more jobs get dispatched
than CPUs can process. This parameter can be:
- None, in which case all the jobs are immediately
created and spawned. Use this for lightweight and
fast-running jobs, to avoid delays due to on-demand
spawning of the jobs
- An int, giving the exact number of total jobs that are
spawned
- A string, giving an expression as a function of n_jobs,
as in '2*n_jobs'
iid : boolean, default=True
If True, the data is assumed to be identically distributed across
the folds, and the loss minimized is the total loss per sample,
and not the mean loss across the folds.
cv : int, cross-validation generator or an iterable, optional
Determines the cross-validation splitting strategy.
Possible inputs for cv are:
- None, to use the default 3-fold cross validation,
- integer, to specify the number of folds in a `(Stratified)KFold`,
- An object to be used as a cross-validation generator.
- An iterable yielding train, test splits.
For integer/None inputs, if the estimator is a classifier and ``y`` is
either binary or multiclass, :class:`StratifiedKFold` is used. In all
other cases, :class:`KFold` is used.
Refer :ref:`User Guide <cross_validation>` for the various
cross-validation strategies that can be used here.
refit : boolean, or string default=True
Refit an estimator using the best found parameters on the whole
dataset.
For multiple metric evaluation, this needs to be a string denoting the
scorer that would be used to find the best parameters for refitting
the estimator at the end.
The refitted estimator is made available at the ``best_estimator_``
attribute and permits using ``predict`` directly on this
``RandomizedSearchCV`` instance.
Also for multiple metric evaluation, the attributes ``best_index_``,
``best_score_`` and ``best_parameters_`` will only be available if
``refit`` is set and all of them will be determined w.r.t this specific
scorer.
See ``scoring`` parameter to know more about multiple metric
evaluation.
verbose : integer
Controls the verbosity: the higher, the more messages.
random_state : int, RandomState instance or None, optional, default=None
Pseudo random number generator state used for random uniform sampling
from lists of possible values instead of scipy.stats distributions.
If int, random_state is the seed used by the random number generator;
If RandomState instance, random_state is the random number generator;
If None, the random number generator is the RandomState instance used
by `np.random`.
error_score : 'raise' (default) or numeric
Value to assign to the score if an error occurs in estimator fitting.
If set to 'raise', the error is raised. If a numeric value is given,
FitFailedWarning is raised. This parameter does not affect the refit
step, which will always raise the error.
return_train_score : boolean, default=True
If ``'False'``, the ``cv_results_`` attribute will not include training
scores.
Attributes
----------
cv_results_ : dict of numpy (masked) ndarrays
A dict with keys as column headers and values as columns, that can be
imported into a pandas ``DataFrame``.
For instance the below given table
+--------------+-------------+-------------------+---+---------------+
| param_kernel | param_gamma | split0_test_score |...|rank_test_score|
+==============+=============+===================+===+===============+
| 'rbf' | 0.1 | 0.8 |...| 2 |
+--------------+-------------+-------------------+---+---------------+
| 'rbf' | 0.2 | 0.9 |...| 1 |
+--------------+-------------+-------------------+---+---------------+
| 'rbf' | 0.3 | 0.7 |...| 1 |
+--------------+-------------+-------------------+---+---------------+
will be represented by a ``cv_results_`` dict of::
{
'param_kernel' : masked_array(data = ['rbf', 'rbf', 'rbf'],
mask = False),
'param_gamma' : masked_array(data = [0.1 0.2 0.3], mask = False),
'split0_test_score' : [0.8, 0.9, 0.7],
'split1_test_score' : [0.82, 0.5, 0.7],
'mean_test_score' : [0.81, 0.7, 0.7],
'std_test_score' : [0.02, 0.2, 0.],
'rank_test_score' : [3, 1, 1],
'split0_train_score' : [0.8, 0.9, 0.7],
'split1_train_score' : [0.82, 0.5, 0.7],
'mean_train_score' : [0.81, 0.7, 0.7],
'std_train_score' : [0.03, 0.03, 0.04],
'mean_fit_time' : [0.73, 0.63, 0.43, 0.49],
'std_fit_time' : [0.01, 0.02, 0.01, 0.01],
'mean_score_time' : [0.007, 0.06, 0.04, 0.04],
'std_score_time' : [0.001, 0.002, 0.003, 0.005],
'params' : [{'kernel' : 'rbf', 'gamma' : 0.1}, ...],
}
NOTE
The key ``'params'`` is used to store a list of parameter
settings dicts for all the parameter candidates.
The ``mean_fit_time``, ``std_fit_time``, ``mean_score_time`` and
``std_score_time`` are all in seconds.
For multi-metric evaluation, the scores for all the scorers are
available in the ``cv_results_`` dict at the keys ending with that
scorer's name (``'_<scorer_name>'``) instead of ``'_score'`` shown
above. ('split0_test_precision', 'mean_train_precision' etc.)
best_estimator_ : estimator or dict
Estimator that was chosen by the search, i.e. estimator
which gave highest score (or smallest loss if specified)
on the left out data. Not available if ``refit=False``.
For multi-metric evaluation, this attribute is present only if
``refit`` is specified.
See ``refit`` parameter for more information on allowed values.
best_score_ : float
Mean cross-validated score of the best_estimator.
For multi-metric evaluation, this is not available if ``refit`` is
``False``. See ``refit`` parameter for more information.
best_params_ : dict
Parameter setting that gave the best results on the hold out data.
For multi-metric evaluation, this is not available if ``refit`` is
``False``. See ``refit`` parameter for more information.
best_index_ : int
The index (of the ``cv_results_`` arrays) which corresponds to the best
candidate parameter setting.
The dict at ``search.cv_results_['params'][search.best_index_]`` gives
the parameter setting for the best model, that gives the highest
mean score (``search.best_score_``).
For multi-metric evaluation, this is not available if ``refit`` is
``False``. See ``refit`` parameter for more information.
scorer_ : function or a dict
Scorer function used on the held out data to choose the best
parameters for the model.
For multi-metric evaluation, this attribute holds the validated
``scoring`` dict which maps the scorer key to the scorer callable.
n_splits_ : int
The number of cross-validation splits (folds/iterations).
Notes
-----
The parameters selected are those that maximize the score of the held-out
data, according to the scoring parameter.
If `n_jobs` was set to a value higher than one, the data is copied for each
parameter setting(and not `n_jobs` times). This is done for efficiency
reasons if individual jobs take very little time, but may raise errors if
the dataset is large and not enough memory is available. A workaround in
this case is to set `pre_dispatch`. Then, the memory is copied only
`pre_dispatch` many times. A reasonable value for `pre_dispatch` is `2 *
n_jobs`.
See Also
--------
:class:`GridSearchCV`:
Does exhaustive search over a grid of parameters.
:class:`ParameterSampler`:
A generator over parameter settins, constructed from
param_distributions.
"""
def __init__(self, estimator, param_distributions, n_iter=10, scoring=None,
fit_params=None, n_jobs=1, iid=True, refit=True, cv=None,
verbose=0, pre_dispatch='2*n_jobs', random_state=None,
error_score='raise', return_train_score=True):
self.param_distributions = param_distributions
self.n_iter = n_iter
self.random_state = random_state
super(RandomizedSearchCV, self).__init__(
estimator=estimator, scoring=scoring, fit_params=fit_params,
n_jobs=n_jobs, iid=iid, refit=refit, cv=cv, verbose=verbose,
pre_dispatch=pre_dispatch, error_score=error_score,
return_train_score=return_train_score)
def _get_param_iterator(self):
"""Return ParameterSampler instance for the given distributions"""
return ParameterSampler(
self.param_distributions, self.n_iter,
random_state=self.random_state)


innerprods module¶
-
innerprods.
inner0_j1k1
(j, k)[source]¶ Calculates the L2 inner product <P_j1, P_k1>
- Parameters
k (j,) – indices for the monomials P_j1, P_k1
- Returns
L2 inner product <P_j1, P_k1>
-
innerprods.
inner0_j1k2
(j, k)[source]¶ Calculates the L2 inner product <P_j1, P_k2>
- Parameters
k (j,) – indices for the monomials P_j1, P_k2
- Returns
L2 inner product <P_j1, P_k2>
-
innerprods.
inner0_j2k2
(j, k)[source]¶ Calculates the L2 inner product <P_j2, P_k2>
- Parameters
k (j,) – indices for the monomials P_j2, P_k
- Returns
L2 inner product <P_j2, P_k2>
-
innerprods.
inner0_j3k3
(j, k)[source]¶ Calculates the L2 inner product <P_j3, P_k3>
- Parameters
k (j,) – indices for the monomials P_j3, P_k3
- Returns
L2 inner product <P_j3, P_k3>
-
innerprods.
inner_dict
= {(1, 1): <function inner0_j1k1>, (1, 2): <function inner0_j1k2>, (1, 3): <function inner0_j1k3>, (2, 2): <function inner0_j2k2>, (2, 3): <function inner0_j2k3>, (3, 3): <function inner0_j3k3>}¶ vals_dict maps the values 1, 2, 3 to the functions alpha, beta, and gamma. This dictionary, along with norm_dict are used in the computation of the values and normal derivatives of the polynomials P_jk (k = 1, 2, 3) on the boundary of SG. The functions are based on the Kasso, Tuley paper.


_The_Original_Kings_of_Comedy_ (R) *** (out of ****)
Normal film review rules don't necessarily apply to _The_Original_Kings_of_Comedy_. Despite being "a Spike Lee Joint," this film of the popular stand-up comedy tour featuring Steve Harvey, D.L. Hughley, Cedric the Entertainer, and Bernie Mac is completely devoid of his trademark razzle dazzle; Lee shoots the concert as matter-of-factly as an HBO comedy special. While not making for the most visually inventive of cinema, the straightforward approach puts in proper focus the film's appeal: four talented guys simply being very funny.
Anyone familiar with the stand-up shows from which most of the four first gained notice--BET's _Comicview_ and HBO's _Def_Comedy_Jam_--knows that in being funny, these guys are also rather profane. Audiences whose only previous experience with Harvey and Cedric is their work on the former's eponymous WB sitcom, or with Hughley on his ABC-to-UPN transplant _The_Hughleys_, are in for a shock--the stars of these family-skewed shows toss off four-letter words with the best (worst?) of them. Prudes may find the amount of profanity ridiculously excessive, but it's an integral part of the comedians' verbal arsenal. Shock value isn't so much the intent as a side effect; the words are used to punctuate and underscore their ideas and observations, many of which revolve around the differences between blacks and whites.
While that inevitably leads to overlap between the four's routines--and a certain feeling of repetition--each performer carves out their own distinct personality. Harvey serves as emcee, and he's the smooth romantic, the highlight of his sets (he does a bit between each act) being a tribute to '70s old school soul that includes a hilarious, on-target rip on rap/hip-hop concerts. Hughley is the energetic live wire, closing out his routine with jabs at random audience members. Cedric is the most laid-back--and most impressively coordinated; his dance moves got both the filmed and live audiences going.
Mac's aggressive closing set is at once the most incendiary and the most truthful. His routine could share the title of the central manifesto in _Jerry_Maguire_, "The Things We Think and Do Not Say"; nothing and no one is safe as Mac talks about wanting to beat sense into naughty children and launches into an extended bit involving stuttering. Much of his material could easily offend, but a lot of it comes within a disarmingly honest context, such as the jokes involving his nieces and nephew, the custody of whom was taken away from his drug-addicted sister and given to him. Of course, the comedic meat of the jokes derives from his creative embellishment, but there is the ring of hard truth in the jokes' foundation.
In an attempt to break the stage-and-crowd visual monotony, Lee sometimes cuts away from the performance to some moments away from the performance arena. Not a bad idea, per se, but these segments, such as a rather pointless one where the four play poker, are largely dull lulls that make the audience too aware of the film's 120-minute running time.
But most of 120 minutes are devoted to what audiences buy a ticket to see: Steve Harvey, D.L. Hughley, Cedric the Entertainer, and Bernie Mac doing their thing. They don't disappoint--and, in turn, neither does _The_Original_Kings_of_Comedy_.
Michael Dequina<EMAIL_ADDRESS>|<EMAIL_ADDRESS>|<EMAIL_ADDRESS>Mr. Brown's Movie Site: http://www.moviereportsite.com CinemaReview Magazine: http://www.CinemaReview.com on ICQ: #25289934 | on AOL Instant Messenger: MrBrown23
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


CustomShaderMaterial
Examples
General
All Material and properties
Environment Map
Planet
Waves
3D Graphs by Steve Trettel
Complex Powers
Hopf Tori
<
</>


Both a software architect and a T-shaped entrepreneur at the same time powered by a systemic product-driven mindset with two decades of experience in building scalable and maintainable software with various tech stacks mostly NodeJS and Java.
I train juniors to senior full-stack developers powering them up as proactive team players.
After telecom and realtime messaging I've been focusing on Marketing Technology, Customer Data Platforms, Customer Experience Automation, developing low-code Data/Orchestration/Automation tools, in recent 5 years.
Sharif University of Technology
MSc. Thesis: Towards an Agile Core Methodology for Software Development
Azad University, Central Tehran Branch
BSc. Project: Implementation of the Iranian Health Portal based on SOA
Various Startups & Tech Companies
Chabok Realtime Solutions
Atieh Dadeh Pardaz
AVVAL MARKET
Aban Parallel Processing
AC&C Basamad Co.
AC&C Basamad Co.
Javaneh Narmafzar (ObjectJ Co.)
Team Development and Coaching
Leadership and Integrity
Micromanagement
Mobile Growth
SaaS
Time Management
Customer Development
Marketing and Negotiation
Forward-Thinking
© Copyrights Behrad Zari. All Rights Reserved


You connect your app to the internet by placing it behind the tazzy network proxy, a service provided by TAS.
To connect tazzy to your app, you need to set the "back end server" field for your app to point at your server's public internet address.
In most HR systems today, apps make API calls against the central system, not the other way around (and not from app to app).
In TAS, there is no central system. Any app can call an API on any other app. This peer to peer model means that, except for the simplest of apps, you'll need to mount API endpoints in your server, and allow inwards API traffic to them.
As well as incoming API traffic, your app may also support incoming SSO-protected traffic, as well as normal incoming traffic (i.e. nothing to do with TAS), so the overall picture is like this:
| incoming SSO traffic
|
| | normal incoming
| | web traffic
| |
| v
| +-------------------+
| |-------------------|
+---------------> || ||
|| ||
incoming API || ||
traffic || || outgoing API traffic
+---------------> || yourapp.com || +------------------+
| |-------------------| |
| +-------------------+ |
| |
| |
+-|----------------------------------------------------------|--+
| | v |
| |
| +--------+ +--------+ |
| |--------| +--------+ |--------| |
| || || |--------| || || |
| || || || || || || |
| |--------| || || |--------| |
| +--------+ |--------| +--------+ |
| +--------+ |
| |
| other installed apps + TAS core |
+---------------------------------------------------------------+
TAS uses the following industry standards for securing incoming and outgoing API and SSO traffic:
| Type of traffic | Security |
|---|---|
| Core APIs | HMAC |
| tenant APIs | OAuth |
| SSO | SAML 2 |
Once your app is sitting behind tazzy, all incoming API and SSO traffic passes through tazzy, as does all outgoing API traffic.
Since tazzy works at the network level, instead of libraries/SDKs, you can build your app in any language/framework.
Tazzy deals with:
Once connected, the network paths look like this:
| incoming SSO traffic (https://communityapps.aotal.com/t/{tenant}/...)
|
| | normal incoming (https://yourapp.com/...)
| | web traffic
| +---+ | +---+
| | | v | |
| | | +-------------------+ | tazzy
| | | |-------------------| | |
+---------------> || || | |
| | || || | |
incoming API || || | |
traffic | || || | | outgoing API traffic
+---------------> || yourapp.com || +------------------+
| | | |-------------------| | | |
| | | +-------------------+ | | |
| | tazzy | | |
| | | | | |
| +---+ +---+ |
| back end server = e.g. |
| https://yourapp.com:8081/myapp |
| |
| |
+-|----------------------------------------------------------|--+
| | v |
| |
| +--------+ +--------+ |
| |--------| +--------+ |--------| |
| || || |--------| || || |
| || || || || || || |
| |--------| || || |--------| |
| +--------+ |--------| +--------+ |
| +--------+ |
| |
| other installed apps + TAS core |
+---------------------------------------------------------------+
Note: while developing your app, it can be convenient to run your server code on your personal machine and then use a tool like ngrok to expose it to the internet.
While tazzy handles all HMAC, OAuth and SAML on behalf of your app, the path between your app and tazzy should still be verified. To do this:
In future Aotal plans to enable you to host the tazzy system within your own network. For now, your app must use the community tazzy, and the app settings pages in the developer site reflect this.


Full name:
org.apache.openejb.maven:tomee-maven-plugin[:Current Version]:deploy
Description:
Attributes:
| Name | Type | Since | Description |
|---|---|---|---|
| path | String | - | (no description) User property is: tomee-plugin.archive. |
| Name | Type | Since | Description |
|---|---|---|---|
| password | String | - | (no description) User property is: tomee-plugin.pwd. |
| realm | String | - | (no description) User property is: tomee-plugin.realm. |
| systemVariables | Map | - | (no description) |
| tomeeHost | String | - | (no description) Default value is: localhost. User property is: tomee-plugin.host. |
| tomeeHttpPort | int | - | (no description) Default value is: 8080. User property is: tomee-plugin.http. |
| useBinaries | boolean | - | (no description) Default value is: false. User property is: tomee-plugin.binary. |
| user | String | - | (no description) User property is: tomee-plugin.user. |
path:
user:


DOWNLOADS
Download Predator Stormbreaker Kernel and Some other cool Stuff from here. Alternative host for Downloads - XDA. You can check out NOTES in our Support Group for more downloads.
HMP - Newcam
- ✓ Only flash this version on ROMs which support newcam
- ✓ As Stable as the Oldcam build
- ✓ If Camera not working after Flashing this kernel variant. Then, dirty flash the oldcam version in custom recovery
HMP - Oldcam
- ✓ 95% of the custom ROMs supports Oldcam Kernel
- ✓ Many users selected this build as their favourite one
- ✓ Stable and Flashable on Custom ROMs & Miui based ROMs (With Patch)
EAS
- ✓ Provides a Smooth UI interaction experience. Experience butter touch UI with this build.
- ✓ Gives decent battery backup for many users
- ✓ Best for Eas based ROMs & Some HMP based too
- Recommended for Gaming
Extras
Miui Patch
- ✓ Flash patch in recovery after Flashing Oldcam Kernel
- ✓ Only Flash this zip on Miui based ROMs
- ✓ You can use Camera, Wifi etc. on Miui with custom Kernels with the given patch file
- ✓ Credits for this Patch - Pro @dwaynesai
Extras
Revert Patch
- ✓ This patch reverts the Miui Patch U have flashed earlier to Use a custom Kernel on MIUI
- ✓ Don't flash on any custom ROMs
- ✓ NOTE - If u don't know What it is. Don't flash it!!
HOT 🔥
Wallpapers & Images
- ✓ Wanna want some cool Wallpapers/Images/Splashes
- ✓ Cool Images shared by Our Kernel lovers
- ✓ Credits To :
• Jaack08
• BOrn_2_be_wiLD • Mybodynotyours
• Letsmakeandro


Amazon.com
This website appears to have no deals
Stores
Visit store
Visit store
Visit store
Visit store
Visit store
Visit store
New Coupons
Found the deals we don't have?
Suggest new coupons


Dark Light
Color Scheme: Monochrome Complementary Triad Split Complementary Analogous
Separation Angle:


Man dressed as Napoleon 'fell in river with his lover's severed arms in backpack'
The St Petersburg State University lecturer Oleg Sokolov apparently intended to kill himself after dumping his girlfriend Anastasia Yeschenko's remains
by Matthew Dresch, https://www.mirror.co.uk/authors/matthew-dresch/A Russian professor was dressed as Napoleon when he drunkenly fell into a river with his lover's severed arms in his backpack, according to reports.

Ms Yeschenko's head and body were found at her teacher's flat after Sokolov fell into a river while trying to dump her remains.
The historical re-enactor reportedly intended to kill himself while dressed as Napoleon after disposing of her body.
It is said the teacher accidentally killed his student after they got into an argument.
He is now in hospital suffering from hypothermia after being dragged out of St Petersburg's Moyka River on Saturday morning.
In his backpack were two female arms severed at the elbow and a gun.
The St Petersburg State University lecturer is renowned for being an expert on the Napoleonic wars, although he was also known for his alcoholism and mood swings, the Mail Online reports.
A saw covered in blood was also found at the professor's flat in St Petersburg.
A criminal case for murder has been opened, say law enforcement sources.
Sokolov was president of the Russian Association of Military History and is now a member of the body’s scientific council.
He has worked as a technical adviser to European television broadcasters on films depicting the Napoleonic era, and he was made a knight of the Legion of Honour in France in 2003.


|
Platinum (1) (1 left) |
Gold (3) (3 left) |
Silver (4) (4 left) |
Bronze (5) (5 left) |
Individual (10) (10 left) |
Business day (1) (1 left) |
|
|---|---|---|---|---|---|---|
| Logo on Main Site | Yes | Yes | Yes | Yes | Yes | Yes |
| Logo on T-Shirts | Yes | Yes | ||||
| Logo on Lanyard | Yes | |||||
| Logo on Delegate Badge | Yes (front) | Yes (front) | Yes (reverse) | |||
| Logo on Business Day Badge | Yes (front) | Yes (reverse) | Yes | |||
| Welcome or closing remarks in keynote | Yes | |||||
| Opportunity to put flyers / gifts in delegate bags | Yes | Yes | Yes | Yes | ||
| Exhibition Space | Yes | Yes | Yes | |||
| Delegate Passes | Yes (3) | Yes (3) | Yes (2) | Yes (2) | Yes(1) | |
| Business Day Passes | Yes (1) | Yes (2) | ||||
| Room sponsorship | Yes | |||||
| Social Media Announcements | Yes | Yes | Yes | Yes | ||
| Constant thanks | Yes | Yes | Yes | Yes | Yes | |
|
Price |
£1,750.00 |
£800.00 |
£500.00 |
£150.00 |
£50.00 | £500.00 |


2/Mar 2016
2 min. read
New Programmer Programming Myths Its a PITA when introducing programming to beginners that there is some unwritten rule somewhere that certain things are just too hard to tackle at first. So the student is introduced to crappy concepts and thus doesn’t touch the “advance” stuff until it is too late - i.e. they are sat there wondering why their production code is crap, slow and buggy. Dont talk about threads This is annoying - no matter what you feel about threads, we live in an async world, it’s fine not to talk about about threads but what are my alternatives.
24/Feb 2016
6 min. read
Environment Setup Use NVM Use Node js Scaffold a WebApp with YeoMan source YeoMan Guide and Meet Yeoman Install yo, grunt-cli, bower, generator-angular and generator-karma npm install -g grunt-cli bower yo generator-karma generator-angular I am opinionated in how I use Ruby in my system. I use rbenv and ruby-build Install the compass gem: gem install compass Either clone my github page or if you really want to learn, do it from scratch.
1/Feb 2016
1 min. read
Today I am pleased to learn that Swagger has been adopted/donated to the Open API Initiative, anyone who has worked with me on any project will know along with many “truths” I apply to any of my project, I always adopt an “API First Design” and use Swagger as a way to document the api. I find this approach works for cross-platform team and even remote ones as it enables back-end to get on with the task at hand without front-enders and mobile team hovering over I recommended this approach when initial architecture designs for HiHo were taking place and we ended up utilising the Clojure Ring-Swagger from day -1.
7/Jan 2016
2 min. read
Having the been to a few hackathons, I have witnessed the somewhat explosive fame of a few entrants. Beyond what they have built - most people build really awesome things - I have noticed a similarity to those who go on family.. Its really all about the narrative, the ability to put in words ( and stir the emotional space) with alluring pictures and anecdotes. To break into the field, you have to have a good combination of telling a good story.
4/Jun 2014
2 min. read
Apple has just released a brand new programming language, I wont go into any of the details as better men have already evaluated it. My excitement is not on the language itself but rather the suite of tools that comes with it. Quoting directly from the release notes. Interactive. Use Swift interactively to experiment with your ideas and see instant results. Unified. A complete replacement for both the C and Objective-C languages.
24/Apr 2014
1 min. read
As you may or may not know - I run PigstyCoders. It is a small yet global boutique with clients across 4 continents and 10 countries. We love and are active in the open-source community and give back whenever possible, either through hackathons, workshops and giveaways. I have always had a passion for Africa and it’s potential and I think Africa is the next frontier in the digital evolution, hence why are doing our best to enable local expertise, through workshops and talks.
9/Mar 2014
1 min. read
I am a huge fan of Git and have been for many years. I tend to go through a lot of developer machines and thus will need to set up my dev environment really quickly - I only use Linux or Apple’s Mac so a shell script normally works for me. Two invaluable tools I have come to love over the years is SourceTree and P4Merge by Perforce. As an aside Perforce is actually a proprietary version control system used in Enterprise but P4Merge is a free tool.
18/Jan 2013
1 min. read
A workshop I gave on developing for Mobile and the strategy to take. Mobile development The deck gives some very basic introduction.
4/Sep 2012
1 min. read
Rails Asset Pipeline - rails book Efficiency in Production One of the best things about the asset pipeline is that it automatically results in assets that are optimized to be efficient in a production application. Traditional methods for organizing CSS and JavaScript involve splitting functionality into separate files and using nice formatting (with lots of indentation). While convenient for the programmer, this is inefficient in production; including multiple full-sized files can significantly slow page-load times (one of the most important factors affecting the quality of the user experience).
3/Sep 2012
1 min. read
http://aws.amazon.com/about-aws/whats-new/2010/12/06/announcing-amazon-route-53-dns-service/ https://dnsimple.com/domains/new http://www.nettica.com/Prices/Default.aspx http://www.dnsmadeeasy.com/ My features Aname, CName, DynamicDNS, API, Cheap / 10s - 100s of domains, TTL (not that these are respected) setup, docs, How do these Compare? Background Always used Linode DNS manager, but not suitable for everything - especially A-Name
3/Sep 2012
2 min. read
Source: http://stackoverflow.com/questions/1388467/reading-epub-format The EPUB format brings together a bunch of different specifications / formats: one to say what the content of the book should look like (a subset of XHTML 1.1 + CSS) one to define a “manifest” that lists all of the files that make up that content (OPF, which is an XML file) one to define how everything is packaged up (OEBPS: a zip file of everything in the manifest plus a few extra files) The specs look a bit daunting but actually once you’ve got the basics (unzipping, parsing XML) down it’s not particularly difficult or complex.
16/Aug 2012
1 min. read
The benefits of keeping things local, Working across machines- I have 4 physical machines I use daily and countless servers dotted around the world, I can never remember the shell commands for any particular project so I created build scripts. I always hated having to rebuild dev environments hence I loved RVM. The RBENV came along and I fell in love. Used in conjunction with a Bundler and --path option, one can get a pretty awesome build going that is isolated and local just to that directory!
16/Aug 2012
2 min. read
Do you want to port those brilliant Nokia applications and QT based apps to Android without rewriting your code or having to learn what a Java Interface is? Necessitas to the rescue! - though you still have to learn Java if you want to be serious on the Android, but I digress. Necessitas allows you port and write QT based applications for Android. For those who are familiar with QT - it is/was the best C++ framework ever invented - opinions clearly my own.
22/Jun 2011
1 min. read
22 June 2011 - Amsterdam This is a short dump of my notes to a customer who hacked the Android framework to create a custom build for their project. The resulting system was unstable and my job was to find out why (and fix it). Comparing a stock android emulator (both 2.2 and 2.3), we see comparable values for highly graphic intensive apps. The difference in system-server could be down to our additions and the amount of processes - for each process needs to communicate it’s state and activities to system_server (package manager, activity manager etc, ContentProvider resolver), the more the process, the more the messages as the framework need to know which activities, services, providers and broadcast is running.


The igx-select allows you to select a single item from a drop-down list. The following sample demonstrates the component defined with groups.
You can read more about how to configure igx-select in the README or the official documentation.


Work Day Scheduler
A simple calendar app for scheduling your work day
9am
Btn
10am
Btn
11am
Btn
12pm
Btn
1pm
Btn
2pm
Btn
3pm
Btn
4pm
Btn
5pm
Btn


Only a third of Modern Warfare players have beaten the campaign
by Jim HargreavesIt’s been almost a month since Infinity Ward launched Call of Duty: Modern Warfare, the latest AAA shooter in Activision’s power selling franchise.
Even back when the original Modern Warfare broke onto the scene back in 2008, there were reports that many who owned a copy of the game dove straight into the multiplayer without completing (or sometimes even touching) the campaign.
According to stats mined from this year’s gritty reboot, only a third of players managed to beat its cinematic singleplayer portion with a much smaller percentage having cleared it on the game’s toughest difficulty settings.
The latest PlayStation trophy data for Call of Duty: Modern Warfare reveals that 33.1% of all players had earned the “Tea Time” trophy awarded at the end of the campaign while 2.4% had earned the “Out of the Fire” gold trophy which pops after you’ve beat the game on either Veteran or Realism difficulty.
There are limitations to exactly how accurate that figure is though it’s a solid indicator to go by. Those who haven’t got an internet connection won’t be able to register their PS4 trophy information though this group of players would be a very small minority.
Of course we have to take into account those who picked the game up on other systems including the Xbox One and PC (neither offering comprehensive achievement data) though it seems unlikely player habits would drastically differ between platforms.
Taking a closer look at the trophy stats harvested there were a few other interesting observations. 0.8% of those who have played the game successfully bagged Modern Warfare’s “Tier One” platinum trophy.
- Call of Duty: Modern Warfare Review
- Is Modern Warfare’s campaign the best Call of Duty has ever done?
- Modern Warfare’s multiplayer feels fresh, yet oh so punishing
This year’s Call of Duty has a notably simpler pool of trophies to unlock with none of them being tied to modes outside the singleplayer campaign.
The two rarest trophies (bar the platinum) are “Clean House” and “We Own the Night”, at 1.2% and 1.1% respectively. Both involve completing a level under very specific conditions and some users have reported them as being bugged.
Finally, it’s worth mentioning Call of Duty secondary trophy list. It only contains one trophy and that’s tied to the Special Ops co-op mode. Only 0.3% of players unlocked the “Liberation” bronze trophy which require you to complete all of the Spec Ops missions available. Almost three times that number have earned the platinum, underlining that the mode’s reinvention really isn’t all that popular.


Prologue: Prerequisites¶
Your computer needs the following computer-programming tools to participate. Verify you have them working before you begin.
A command-line interface¶
Whether you know about it or not, there should be a way to open a window and directly issue commands to your operating system. Different operating systems give this tool slightly different names, but they all have some form of it.
On Windows this is called the “command prompt.” On MacOS it is called the “terminal.”
On Windows 10, we recommend you install the Windows Subsystem for Linux and select the Ubuntu distribution from the Windows Store. This will give you access to a generic open-source terminal without all the complications and quirks introduced by Windows. On MacOS, the standard terminal app will work fine.
Python 3.5 or higher¶
Python is a free and open-source computer programming language. It’s one of the most popular in the world and praised by its supporters as clear and easy to read.
That makes it ideal for beginners and is partly why it’s been adopted by professionals in many fields, ranging from engineering and web development to journalism and music.
You can check if Python is already installed on your computer by visiting your command line and entering the following:
python --version
You should see something like this after you hit enter:
Python 3.5.2
If not, you’ll need to install Python on your system.
If you see a number starting with 2, like say …
Python 2.7.12
… then you have an outdated version of Python and will need to upgrade to a version starting with a three. You can probably complete the class without doing so, but the maintainers of Python are gradually phasing out version two and officially recommend you upgrade.
Instructions for both new installations and upgrades can be found here.


Hookah bar
& lounge
SORRY, THE PAGE WAS NOT FOUND
You could have mistyped the URL, or the page has moved.


Byron Virgil Keyes
Hello my name is Byron Keyes I come from working in call center environments. Most recently at Nationwide in the claims intake department. I have wanted to learn to code since it was described to me as having a super power. I found out about coding bootcamps in 2016 and I attended my first class at DeltaV and loved it. I have worked on many different teams with many different people and have always found a way to be a team player and have success.


Elon Musk
Home
Popular Photos
Popular Tweets
Contact Me
(current)
Reach out to the creator of this tribute
First Name
Last Name
Email
Address
Address line 2
City
State
Choose...
...
Zip
Submit Form


Oh yes, it's important.
settings menu
Read me.
function greeting() { console.log("hello"); }
Read me too.
too
Just ignore this.
And you can quote me on this...
Ugh.


Tools & Resources
Home
|
Tools
CRO
|
Analytics
|
SEO
|
PWA & AMP
|
Perf
|
Dev
|
Social
|
Crypto
|
More
A/B Test Calculator
Simple & Advanced Hypothesis Kit
Google Analytics URL Builder
Measurement Protocol Hit Builder
Revenue Growth Calculator
Google Search
URL Decoder / Encoder
Bookmarklets
Test
Dashboard
Realtime Dashboard
Vreeman Cloud
Vreeman KB
More Tools
A bunch more links.
Index of gifs
Random Galaxy Art
Suits Giphy
Hans Giphy
Cityguys.nl Giphy
Slackmojis - The Best Custom Slack Emojis
World Time Buddy
Nitpicker
Hemingway Editor
Privacy Tools
Wielrenjargon
Spotify Playlist tool
Now Playing On Spotify
Organize Your Music On Spotify
Spotify Top Artists & Tracks
Spotify Developer Showcase
Gear Patrol
Uncrate
Bless This Stuff
Goruck
MeisterSinger
Luminox (ANU)
Rolex Oyster Perpetual
Harrington jacket
Flint and Tinder
Red Wing Boots
Noshirt
SuitSupply
O'Mast: The Art of Neapolitan Tailoring
Huel Bars
Huel Powder
First Energy Gum
The Prisoner Workout
How to Do the Shortest Workout Possible
Techmeme
Hacker News
Designer News
Growth Hackers
SparkToro Trending
DataTau
Instapaper Daily
Wait But Why
Stratechery
First Round
Andrew Chen
Marketoonist


|
Hi,
My name is John Yap. I have done a home page here previously at this
url but seriously I think the previous page s***ed big time. Having
graduated from Ngee Ann Polytechnic last year, I am currently working
in National University of Singapore, Faculty of Arts and Social Sciences.
Dwelling in the Centre for IT and Applications at the Dean's office,
I am one of the webmasters who design web sites for the various departments
and produces multimedia educational development courseware/software
for academic purposes. I am all ready to take on the web challenge
on a wider scale. I seriously hate talking about myself. I would rather let the music I listen to speak for me. Dun worry, I do not condemn any form of music here because personally I think it is a way people communicate their life, style, feelings, thoughts et al to other people.  Pretentious? Think what you want. So long as it doesn't impinge on my physical life here, you can say or do what you want. |
The artistes I featured here are but a small portion of what I hear. They were chosen not because of I love them that much but for reasons that I think they deserve the necessary attention from people visiting the site and that they are just not given the exposure they need to make future records. So guys, Keep Shining! >> Now on to the big showcase for you guys! Follow this link >> John's Workbench where you can see the plethora of work that I have done. See Ya! I
used to have a guest book here at the moment but I am still in the middle
of locating a file. You can email me here<EMAIL_ADDRESS>or<EMAIL_ADDRESS>and tell me how much you love this site or simply hate this site! Thank
you! *muaks* :o) |
|
|
|


[gecode-users] saving the way to one of the solution in a file
Mikael De Bie
mikael.debie at student.uclouvain.be
Sun Dec 10 18:01:16 CET 2006
On Mon, 2006-12-04 at 14:41 +0100, Guido Tack wrote:
> > nevertheless I wonder why the webpage http://www.gecode.org/gecodej/
> > indicates that Gecode/J allows to implement search engines using
> > copying
> > and recomputation.
> >
> > Don't you think I could program a new search engine totally in java as
> > it's done for Gist ?
>
> Sorry, I maybe wasn't very clear on this. You can write the search
> engine in Java, it's just that you can't take an existing one and
> modify it, but you'll have to start from scratch. I wanted to suggest
> that you look at the C++ code, and then more or less port that to
> Java, adjusting it to your needs. The space interfaces are very
> similar in C++ and Java, so porting stuff is relatively easy.
>
> Cheers,
> Guido
>
I've finally decided to use gecode instead of gecode/J so that I could
modify the existing classes dfs.icc, reco-stack.icc and search.hh rather
than implement the whole from nothing.
I've managed to get the way to the solution found, that is the list of
alternatives to follow. But I don't really understand how to rebuild the
stack.
In my opinion, I have to push a new ReCoNode in the stack for each
alternative.
I've tried to add a method in DFSEngine that rebuild the stack:
// Reconstruct the stack from the way (ex: way = "0110111")
forceinline void
DfsEngine::setWay(string way){
rcs.reset();
const BranchingDesc* desc = rcs.push(cur, NULL);
for(int i=0;i<way.length();i++){
//Get the integer in ith pos in the way
string stmp = way.substr(i,1);
const char* tmp = stmp.c_str();
int j = atoi(&tmp[0]);
//push a new ReCoNode in the stack
cur->commit(desc,j);
desc = rcs.push(cur,NULL);
}
}
Once the stack is rebuild, I thought I could simply call the method
next().
But it doesn't seem to work...
I don't get any error, but the program simply stops when j = 1 but I
don't know why...
Has anybody any idea to help me ?
Thanks in advance
Mikael
More information about the gecode-users
mailing list


r"""
This package adds support for CUDA tensor types, that implement the same
function as CPU tensors, but they utilize GPUs for computation.
It is lazily initialized, so you can always import it, and use
:func:`is_available()` to determine if your system supports CUDA.
:ref:`cuda-semantics` has more details about working with CUDA.
"""
import contextlib
import platform
import ctypes
import os
import sys
import torch
import traceback
import warnings
import threading
from torch._six import raise_from
from subprocess import Popen, PIPE
from multiprocessing.util import register_after_fork as _register_after_fork
from ._utils import _get_device_index
_initialized = False
_tls = threading.local()
_initialization_lock = threading.Lock()
_queued_calls = [] # don't invoke these until initialization occurs
_in_bad_fork = False # this global is also used in torch.manual_seed
_original_pid = False
_cudart = None
def find_cuda_windows_lib():
# Override the default search process
# Fixes https://github.com/pytorch/pytorch/issues/20202
# The libary selection will be done in these directories one by one
# 1. [Package Root]\Lib
# That's where our libraries are in, which should be loaded first.
# 2. [Python Root]\Library\bin
# That's where `cudatoolkit` store the cuda libraries.
# 3. Default directories
# That is stored in the environment variable `PATH`.
test_env = os.environ.copy()
old_path = test_env['PATH']
py_dll_path = os.path.join(sys.exec_prefix, 'Library', 'bin')
th_dll_path = os.path.join(os.path.dirname(
os.path.dirname(__file__)), 'lib')
test_env['PATH'] = ';'.join([th_dll_path, py_dll_path, old_path])
proc = Popen(['where', 'cudart64*.dll'], stdout=PIPE,
stderr=PIPE, stdin=PIPE, env=test_env)
out, err = proc.communicate()
out = out.decode().strip()
if len(out) > 0:
if out.find('\r\n') != -1:
out = out.split('\r\n')[0]
cuda_lib_name = os.path.basename(out)
cuda_lib = os.path.splitext(cuda_lib_name)[0]
cuda_lib = str(cuda_lib)
return ctypes.cdll.LoadLibrary(cuda_lib)
else:
return None
[docs]def is_available():
r"""Returns a bool indicating if CUDA is currently available."""
if (not hasattr(torch._C, '_cuda_isDriverSufficient') or
not torch._C._cuda_isDriverSufficient()):
return False
return torch._C._cuda_getDeviceCount() > 0
def _sleep(cycles):
torch._C._cuda_sleep(cycles)
def _load_cudart():
# First check the main program for CUDA symbols
if platform.system() == 'Windows':
lib = find_cuda_windows_lib()
else:
lib = ctypes.cdll.LoadLibrary(None)
if hasattr(lib, 'cudaGetErrorName'):
return lib
raise RuntimeError(
"couldn't find libcudart. Make sure CUDA libraries are installed in a "
"default location, or that they're in {}."
.format('DYLD_LIBRARY_PATH' if platform.system() == 'Darwin' else
'LD_LIBRARY_PATH'))
def _check_driver():
if not hasattr(torch._C, '_cuda_isDriverSufficient'):
raise AssertionError("Torch not compiled with CUDA enabled")
if not torch._C._cuda_isDriverSufficient():
if torch._C._cuda_getDriverVersion() == 0:
# found no NVIDIA driver on the system
raise AssertionError("""
Found no NVIDIA driver on your system. Please check that you
have an NVIDIA GPU and installed a driver from
http://www.nvidia.com/Download/index.aspx""")
else:
# TODO: directly link to the alternative bin that needs install
raise AssertionError("""
The NVIDIA driver on your system is too old (found version {}).
Please update your GPU driver by downloading and installing a new
version from the URL: http://www.nvidia.com/Download/index.aspx
Alternatively, go to: https://pytorch.org to install
a PyTorch version that has been compiled with your version
of the CUDA driver.""".format(str(torch._C._cuda_getDriverVersion())))
def _check_capability():
incorrect_binary_warn = """
Found GPU%d %s which requires CUDA_VERSION >= %d to
work properly, but your PyTorch was compiled
with CUDA_VERSION %d. Please install the correct PyTorch binary
using instructions from https://pytorch.org
"""
old_gpu_warn = """
Found GPU%d %s which is of cuda capability %d.%d.
PyTorch no longer supports this GPU because it is too old.
The minimum cuda capability that we support is 3.5.
"""
CUDA_VERSION = torch._C._cuda_getCompiledVersion()
for d in range(device_count()):
capability = get_device_capability(d)
major = capability[0]
minor = capability[1]
name = get_device_name(d)
if capability == (3, 0) or major < 3:
warnings.warn(old_gpu_warn % (d, name, major, capability[1]))
elif CUDA_VERSION <= 9000 and major >= 7 and minor >= 5:
warnings.warn(incorrect_binary_warn % (d, name, 10000, CUDA_VERSION))
def _lazy_call(callable):
if _initialized:
callable()
else:
# Don't store the actual traceback to avoid memory cycle
_queued_calls.append((callable, traceback.format_stack()))
_lazy_call(_check_capability)
class DeferredCudaCallError(Exception):
pass
[docs]def init():
r"""Initialize PyTorch's CUDA state. You may need to call
this explicitly if you are interacting with PyTorch via
its C API, as Python bindings for CUDA functionality will not
be until this initialization takes place. Ordinary users
should not need this, as all of PyTorch's CUDA methods
automatically initialize CUDA state on-demand.
Does nothing if the CUDA state is already initialized.
"""
_lazy_init()
def _lazy_init():
global _initialized, _cudart, _original_pid, _queued_calls
if _initialized or hasattr(_tls, 'is_initializing'):
return
with _initialization_lock:
# We be double-checked locking, boys! This is OK because
# the above test was GIL protected anyway. The inner test
# is for when a thread blocked on some other thread which was
# doing the initialization; when they get the lock, they will
# find there is nothing left to do.
if _initialized:
return
# It is important to prevent other threads from entering _lazy_init
# immediately, while we are still guaranteed to have the GIL, because some
# of the C calls we make below will release the GIL
if _in_bad_fork:
from sys import version_info
if version_info < (3, 4):
msg = ("To use CUDA with multiprocessing, you must use Python "
"3.4+ and the 'spawn' start method")
else:
msg = ("To use CUDA with multiprocessing, you must use the "
"'spawn' start method")
raise RuntimeError(
"Cannot re-initialize CUDA in forked subprocess. " + msg)
_check_driver()
torch._C._cuda_init()
_cudart = _load_cudart()
_cudart.cudaGetErrorName.restype = ctypes.c_char_p
_cudart.cudaGetErrorString.restype = ctypes.c_char_p
_original_pid = os.getpid()
# Some of the queued calls may reentrantly call _lazy_init();
# we need to just return without initializing in that case.
# However, we must not let any *other* threads in!
_tls.is_initializing = True
try:
for queued_call, orig_traceback in _queued_calls:
try:
queued_call()
except Exception as e:
msg = ("CUDA call failed lazily at initialization with error: {}\n\n"
"CUDA call was originally invoked at:\n\n{}").format(str(e), orig_traceback)
raise_from(DeferredCudaCallError(msg), e)
finally:
delattr(_tls, 'is_initializing')
_initialized = True
def _after_fork(arg):
global _initialized, _in_bad_fork
if _initialized and _original_pid != os.getpid():
_initialized = False
_in_bad_fork = True
_CudaBase.__new__ = _lazy_new
torch._C._cuda_set_run_yet_variable_to_false()
_register_after_fork(_after_fork, _after_fork)
def cudart():
_lazy_init()
return _cudart
class cudaStatus(object):
SUCCESS = 0
ERROR_NOT_READY = 34
class CudaError(RuntimeError):
def __init__(self, code):
msg = cudart().cudaGetErrorString(code).decode('utf-8')
super(CudaError, self).__init__('{0} ({1})'.format(msg, code))
def check_error(res):
if res != cudaStatus.SUCCESS:
raise CudaError(res)
[docs]class device(object):
r"""Context-manager that changes the selected device.
Arguments:
device (torch.device or int): device index to select. It's a no-op if
this argument is a negative integer or ``None``.
"""
def __init__(self, device):
self.idx = _get_device_index(device, optional=True)
self.prev_idx = -1
def __enter__(self):
if self.idx == -1:
return
self.prev_idx = torch._C._cuda_getDevice()
if self.prev_idx != self.idx:
torch._C._cuda_setDevice(self.idx)
_lazy_init()
def __exit__(self, *args):
if self.prev_idx != self.idx:
torch._C._cuda_setDevice(self.prev_idx)
return False
[docs]class device_of(device):
r"""Context-manager that changes the current device to that of given object.
You can use both tensors and storages as arguments. If a given object is
not allocated on a GPU, this is a no-op.
Arguments:
obj (Tensor or Storage): object allocated on the selected device.
"""
def __init__(self, obj):
idx = obj.get_device() if obj.is_cuda else -1
super(device_of, self).__init__(idx)
[docs]def set_device(device):
r"""Sets the current device.
Usage of this function is discouraged in favor of :any:`device`. In most
cases it's better to use ``CUDA_VISIBLE_DEVICES`` environmental variable.
Arguments:
device (torch.device or int): selected device. This function is a no-op
if this argument is negative.
"""
device = _get_device_index(device)
if device >= 0:
torch._C._cuda_setDevice(device)
[docs]def get_device_name(device=None):
r"""Gets the name of a device.
Arguments:
device (torch.device or int, optional): device for which to return the
name. This function is a no-op if this argument is a negative
integer. It uses the current device, given by :func:`~torch.cuda.current_device`,
if :attr:`device` is ``None`` (default).
"""
return get_device_properties(device).name
[docs]def get_device_capability(device=None):
r"""Gets the cuda capability of a device.
Arguments:
device (torch.device or int, optional): device for which to return the
device capability. This function is a no-op if this argument is
a negative integer. It uses the current device, given by
:func:`~torch.cuda.current_device`, if :attr:`device` is ``None``
(default).
Returns:
tuple(int, int): the major and minor cuda capability of the device
"""
prop = get_device_properties(device)
return prop.major, prop.minor
def get_device_properties(device):
if not _initialized:
init() # will define _get_device_properties and _CudaDeviceProperties
device = _get_device_index(device, optional=True)
if device < 0 or device >= device_count():
raise AssertionError("Invalid device id")
return _get_device_properties(device)
<EMAIL_ADDRESS>def stream(stream):
r"""Context-manager that selects a given stream.
All CUDA kernels queued within its context will be enqueued on a selected
stream.
Arguments:
stream (Stream): selected stream. This manager is a no-op if it's
``None``.
.. note:: Streams are per-device. If the selected stream is not on the
current device, this function will also change the current device to
match the stream.
"""
if stream is None:
yield
return
src_prev_stream = current_stream()
if src_prev_stream.device != stream.device:
# The given stream is on a different device; have to restore the
# current_stream on that device on exit as well
with device(stream.device):
dst_prev_stream = current_stream()
torch._C._cuda_setStream(stream._cdata)
try:
yield
finally:
if src_prev_stream.device != stream.device:
torch._C._cuda_setStream(dst_prev_stream._cdata)
torch._C._cuda_setStream(src_prev_stream._cdata)
[docs]def device_count():
r"""Returns the number of GPUs available."""
if is_available():
return torch._C._cuda_getDeviceCount()
else:
return 0
[docs]def current_device():
r"""Returns the index of a currently selected device."""
_lazy_init()
return torch._C._cuda_getDevice()
[docs]def synchronize(device=None):
r"""Waits for all kernels in all streams on a CUDA device to complete.
Arguments:
device (torch.device or int, optional): device for which to synchronize.
It uses the current device, given by :func:`~torch.cuda.current_device`,
if :attr:`device` is ``None`` (default).
"""
_lazy_init()
with torch.cuda.device(device):
return torch._C._cuda_synchronize()
[docs]def ipc_collect():
r"""Force collects GPU memory after it has been released by CUDA IPC.
.. note::
Checks if any sent CUDA tensors could be cleaned from the memory. Force
closes shared memory file used for reference counting if there is no
active counters. Useful when the producer process stopped actively sending
tensors and want to release unused memory.
"""
_lazy_init()
return torch._C._cuda_ipc_collect()
[docs]def current_stream(device=None):
r"""Returns the currently selected :class:`Stream` for a given device.
Arguments:
device (torch.device or int, optional): selected device. Returns
the currently selected :class:`Stream` for the current device, given
by :func:`~torch.cuda.current_device`, if :attr:`device` is ``None``
(default).
"""
_lazy_init()
return torch.cuda.Stream(_cdata=torch._C._cuda_getCurrentStream(
_get_device_index(device, optional=True)))
[docs]def default_stream(device=None):
r"""Returns the default :class:`Stream` for a given device.
Arguments:
device (torch.device or int, optional): selected device. Returns
the default :class:`Stream` for the current device, given by
:func:`~torch.cuda.current_device`, if :attr:`device` is ``None``
(default).
"""
_lazy_init()
return torch.cuda.Stream(_cdata=torch._C._cuda_getDefaultStream(
_get_device_index(device, optional=True)))
[docs]def current_blas_handle():
r"""Returns cublasHandle_t pointer to current cuBLAS handle"""
_lazy_init()
return torch._C._cuda_getCurrentBlasHandle()
[docs]def empty_cache():
r"""Releases all unoccupied cached memory currently held by the caching
allocator so that those can be used in other GPU application and visible in
`nvidia-smi`.
.. note::
:func:`~torch.cuda.empty_cache` doesn't increase the amount of GPU
memory available for PyTorch. See :ref:`cuda-memory-management` for
more details about GPU memory management.
"""
if _initialized:
torch._C._cuda_emptyCache()
[docs]def memory_allocated(device=None):
r"""Returns the current GPU memory occupied by tensors in bytes for a given
device.
Arguments:
device (torch.device or int, optional): selected device. Returns
statistic for the current device, given by :func:`~torch.cuda.current_device`,
if :attr:`device` is ``None`` (default).
.. note::
This is likely less than the amount shown in `nvidia-smi` since some
unused memory can be held by the caching allocator and some context
needs to be created on GPU. See :ref:`cuda-memory-management` for more
details about GPU memory management.
"""
device = _get_device_index(device, optional=True)
return torch._C._cuda_memoryAllocated(device)
[docs]def max_memory_allocated(device=None):
r"""Returns the maximum GPU memory occupied by tensors in bytes for a given
device.
By default, this returns the peak allocated memory since the beginning of
this program. :func:`~torch.cuda.reset_max_memory_allocated` can be used to
reset the starting point in tracking this metric. For example, these two
functions can measure the peak allocated memory usage of each iteration in a
training loop.
Arguments:
device (torch.device or int, optional): selected device. Returns
statistic for the current device, given by :func:`~torch.cuda.current_device`,
if :attr:`device` is ``None`` (default).
.. note::
See :ref:`cuda-memory-management` for more details about GPU memory
management.
"""
device = _get_device_index(device, optional=True)
return torch._C._cuda_maxMemoryAllocated(device)
[docs]def reset_max_memory_allocated(device=None):
r"""Resets the starting point in tracking maximum GPU memory occupied by
tensors for a given device.
See :func:`~torch.cuda.max_memory_allocated` for details.
Arguments:
device (torch.device or int, optional): selected device. Returns
statistic for the current device, given by :func:`~torch.cuda.current_device`,
if :attr:`device` is ``None`` (default).
.. note::
See :ref:`cuda-memory-management` for more details about GPU memory
management.
"""
device = _get_device_index(device, optional=True)
return torch._C._cuda_resetMaxMemoryAllocated(device)
[docs]def memory_cached(device=None):
r"""Returns the current GPU memory managed by the caching allocator in bytes
for a given device.
Arguments:
device (torch.device or int, optional): selected device. Returns
statistic for the current device, given by :func:`~torch.cuda.current_device`,
if :attr:`device` is ``None`` (default).
.. note::
See :ref:`cuda-memory-management` for more details about GPU memory
management.
"""
device = _get_device_index(device, optional=True)
return torch._C._cuda_memoryCached(device)
[docs]def max_memory_cached(device=None):
r"""Returns the maximum GPU memory managed by the caching allocator in bytes
for a given device.
By default, this returns the peak cached memory since the beginning of this
program. :func:`~torch.cuda.reset_max_memory_cached` can be used to reset
the starting point in tracking this metric. For example, these two functions
can measure the peak cached memory amount of each iteration in a training
loop.
Arguments:
device (torch.device or int, optional): selected device. Returns
statistic for the current device, given by :func:`~torch.cuda.current_device`,
if :attr:`device` is ``None`` (default).
.. note::
See :ref:`cuda-memory-management` for more details about GPU memory
management.
"""
device = _get_device_index(device, optional=True)
return torch._C._cuda_maxMemoryCached(device)
[docs]def reset_max_memory_cached(device=None):
r"""Resets the starting point in tracking maximum GPU memory managed by the
caching allocator for a given device.
See :func:`~torch.cuda.max_memory_cached` for details.
Arguments:
device (torch.device or int, optional): selected device. Returns
statistic for the current device, given by :func:`~torch.cuda.current_device`,
if :attr:`device` is ``None`` (default).
.. note::
See :ref:`cuda-memory-management` for more details about GPU memory
management.
"""
device = _get_device_index(device, optional=True)
return torch._C._cuda_resetMaxMemoryCached(device)
def _host_allocator():
_lazy_init()
return torch._C._cuda_cudaHostAllocator()
@contextlib.contextmanager
def _free_mutex():
torch._C._cuda_lock_mutex()
try:
yield
finally:
torch._C._cuda_unlock_mutex()
from .random import *
################################################################################
# Define Storage and Tensor classes
################################################################################
from ..storage import _StorageBase
def _dummy_type(name):
def init_err(self):
class_name = self.__class__.__name__
raise RuntimeError(
"Tried to instantiate dummy base class {}".format(class_name))
return type(storage_name, (object,), {"__init__": init_err})
if not hasattr(torch._C, 'CudaDoubleStorageBase'):
# Define dummy base classes
for t in ['Double', 'Float', 'Long', 'Int', 'Short', 'Char', 'Byte', 'Half', 'Bool', 'BFloat16']:
storage_name = 'Cuda{0}StorageBase'.format(t)
tensor_name = 'Cuda{0}TensorBase'.format(t)
torch._C.__dict__[storage_name] = _dummy_type(storage_name)
torch._C.__dict__[tensor_name] = _dummy_type(tensor_name)
torch._C.__dict__['_CudaStreamBase'] = _dummy_type('CudaStreamBase')
torch._C.__dict__['_CudaEventBase'] = _dummy_type('CudaEventBase')
@staticmethod
def _lazy_new(cls, *args, **kwargs):
_lazy_init()
# We need this method only for lazy init, so we can remove it
del _CudaBase.__new__
return super(_CudaBase, cls).__new__(cls, *args, **kwargs)
class _CudaBase(object):
is_cuda = True
is_sparse = False
def type(self, *args, **kwargs):
with device(self.get_device()):
return super(_CudaBase, self).type(*args, **kwargs)
__new__ = _lazy_new
class DoubleStorage(_CudaBase, torch._C.CudaDoubleStorageBase, _StorageBase):
pass
class FloatStorage(_CudaBase, torch._C.CudaFloatStorageBase, _StorageBase):
pass
class LongStorage(_CudaBase, torch._C.CudaLongStorageBase, _StorageBase):
pass
class IntStorage(_CudaBase, torch._C.CudaIntStorageBase, _StorageBase):
pass
class ShortStorage(_CudaBase, torch._C.CudaShortStorageBase, _StorageBase):
pass
class CharStorage(_CudaBase, torch._C.CudaCharStorageBase, _StorageBase):
pass
class ByteStorage(_CudaBase, torch._C.CudaByteStorageBase, _StorageBase):
pass
class HalfStorage(_CudaBase, torch._C.CudaHalfStorageBase, _StorageBase):
pass
class BoolStorage(_CudaBase, torch._C.CudaBoolStorageBase, _StorageBase):
pass
class BFloat16Storage(_CudaBase, torch._C.CudaBFloat16StorageBase, _StorageBase):
pass
torch._storage_classes.add(DoubleStorage)
torch._storage_classes.add(FloatStorage)
torch._storage_classes.add(LongStorage)
torch._storage_classes.add(IntStorage)
torch._storage_classes.add(ShortStorage)
torch._storage_classes.add(CharStorage)
torch._storage_classes.add(ByteStorage)
torch._storage_classes.add(HalfStorage)
torch._storage_classes.add(BoolStorage)
torch._storage_classes.add(BFloat16Storage)
from . import sparse # noqa: F401
from . import profiler # noqa: F401
from . import nvtx # noqa: F401
from .streams import Stream, Event # noqa: F401