tools/autograd/load_derivatives.py
def check_grad_usage(defn_name, declaration, derivatives):
        """
        Check for some subtle mistakes one might make when writing gradients.
        These mistakes will compile, but will be latent until a function is
        used with double backwards.
        """

        used_grad = 0
        used_grads = 0
        fully_implemented = True
        used_grads_indices = []
        for d in derivatives:
            formula = d['formula']
            used_grad += len(re.findall(IDENT_REGEX.format('grad'), formula))
            used_grads += len(re.findall(IDENT_REGEX.format('grads'), formula))
            fully_implemented = \
                fully_implemented and \
                not re.search(IDENT_REGEX.format('not_implemented'), formula)
            used_grads_indices.extend(used_gradient_indices(formula))
        assert used_grads >= len(used_grads_indices)
        only_used_grads_indices = used_grads == len(used_grads_indices)

        if used_grad and used_grads:
            raise RuntimeError("Derivative definition of {} in derivatives.yaml illegally "
                               "mixes use of 'grad' and 'grads'. Consider replacing "
                               "occurrences of 'grad' with 'grads[0]'".format(defn_name))

        if only_used_grads_indices and set(used_grads_indices) == {0}:
            raise RuntimeError("Derivative definition of {} in derivatives.yaml solely "
                               "refers to 'grads[0]'.  If the first output is indeed the "
                               "only differentiable output, replace 'grads[0]' with 'grad'; "
                               "otherwise, there is a likely error in your derivatives "
                               "declaration.".format(defn_name))

        hardcoded_diff = HARDCODED_DIFFERENTIABLE_OUTPUTS.get(defn_name)
        if hardcoded_diff:
            if used_grad:
                raise RuntimeError("Derivative definition {} has hard-coded differentiable "
                                   "outputs in gen_autograd.py, but used grad (which implies "
                                   "only the first output is differentiable) in its "
                                   "derivative declaration.  You likely meant to write "
                                   "grads[i] for some i instead.".format(defn_name))
            if only_used_grads_indices and set(used_grads_indices) != set(hardcoded_diff):
                raise RuntimeError("Derivative definition {} has hard-coded differentiable "
                                   "outputs {}, but the used grads in the derivative "
                                   "definitions are only {}.  Either your derivatives "
                                   "declaration is wrong, or the value of "
                                   "HARDCODED_DIFFERENTIABLE_OUTPUTS in gen_autograd.py "
                                   "is wrong.".format(defn_name, hardcoded_diff,
                                                      used_grads_indices))
        else:
            if fully_implemented and not used_grad and \
               used_grads and only_used_grads_indices and \
               set(used_grads_indices) != set(range(len(declaration['returns']))):
                raise RuntimeError("Derivative definition of {} in derivatives.yaml does "
                                   "not refer to the gradients of all of its outputs.  Either "
                                   "the derivatives declaration is wrong, OR you have some "
                                   "non-differentiable outputs.  If you have a single "
                                   "differentiable output, make it the first output in ATen "
                                   "and reference its gradient with 'grad'; otherwise, hard "
                                   "code the list of differentiable outputs in "
                                   "HARDCODED_DIFFERENTIABLE_OUTPUTS in gen_autograd.py."
                                   .format(defn_name))

        Check for some subtle mistakes one might make when writing gradients.
        These mistakes will compile, but will be latent until a function is
        used with double backwards.
        
Check for some subtle mistakes one might make when writing gradients.
These mistakes will compile, but will be latent until a function is
used with double backwards.
Check for some subtle mistakes one might make when writing gradients . These mistakes will compile but will be latent until a function is used with double backwards .
def check_grad_usage(defn_name, declaration, derivatives):
        used_grad = 0
        used_grads = 0
        fully_implemented = True
        used_grads_indices = []
        for d in derivatives:
            formula = d['formula']
            used_grad += len(re.findall(IDENT_REGEX.format('grad'), formula))
            used_grads += len(re.findall(IDENT_REGEX.format('grads'), formula))
            fully_implemented = \
                fully_implemented and \
                not re.search(IDENT_REGEX.format('not_implemented'), formula)
            used_grads_indices.extend(used_gradient_indices(formula))
        assert used_grads >= len(used_grads_indices)
        only_used_grads_indices = used_grads == len(used_grads_indices)
        if used_grad and used_grads:
            raise RuntimeError("Derivative definition of {} in derivatives.yaml illegally "
                               "mixes use of 'grad' and 'grads'. Consider replacing "
                               "occurrences of 'grad' with 'grads[0]'".format(defn_name))
        if only_used_grads_indices and set(used_grads_indices) == {0}:
            raise RuntimeError("Derivative definition of {} in derivatives.yaml solely "
                               "refers to 'grads[0]'.  If the first output is indeed the "
                               "only differentiable output, replace 'grads[0]' with 'grad'; "
                               "otherwise, there is a likely error in your derivatives "
                               "declaration.".format(defn_name))
        hardcoded_diff = HARDCODED_DIFFERENTIABLE_OUTPUTS.get(defn_name)
        if hardcoded_diff:
            if used_grad:
                raise RuntimeError("Derivative definition {} has hard-coded differentiable "
                                   "outputs in gen_autograd.py, but used grad (which implies "
                                   "only the first output is differentiable) in its "
                                   "derivative declaration.  You likely meant to write "
                                   "grads[i] for some i instead.".format(defn_name))
            if only_used_grads_indices and set(used_grads_indices) != set(hardcoded_diff):
                raise RuntimeError("Derivative definition {} has hard-coded differentiable "
                                   "outputs {}, but the used grads in the derivative "
                                   "definitions are only {}.  Either your derivatives "
                                   "declaration is wrong, or the value of "
                                   "HARDCODED_DIFFERENTIABLE_OUTPUTS in gen_autograd.py "
                                   "is wrong.".format(defn_name, hardcoded_diff,
                                                      used_grads_indices))
        else:
            if fully_implemented and not used_grad and \
               used_grads and only_used_grads_indices and \
               set(used_grads_indices) != set(range(len(declaration['returns']))):
                raise RuntimeError("Derivative definition of {} in derivatives.yaml does "
                                   "not refer to the gradients of all of its outputs.  Either "
                                   "the derivatives declaration is wrong, OR you have some "
                                   "non-differentiable outputs.  If you have a single "
                                   "differentiable output, make it the first output in ATen "
                                   "and reference its gradient with 'grad'; otherwise, hard "
                                   "code the list of differentiable outputs in "
                                   "HARDCODED_DIFFERENTIABLE_OUTPUTS in gen_autograd.py."
                                   .format(defn_name))
def check_grad_usage ( defn_name , declaration , derivatives ) : used_grad = 0 used_grads = 0 fully_implemented = True used_grads_indices = [ ] for d in derivatives : formula = d [ 'formula' ] used_grad += len ( re . findall ( IDENT_REGEX . format ( 'grad' ) , formula ) ) used_grads += len ( re . findall ( IDENT_REGEX . format ( 'grads' ) , formula ) ) fully_implemented = fully_implemented and not re . search ( IDENT_REGEX . format ( 'not_implemented' ) , formula ) used_grads_indices . extend ( used_gradient_indices ( formula ) ) assert used_grads >= len ( used_grads_indices ) only_used_grads_indices = used_grads == len ( used_grads_indices ) if used_grad and used_grads : raise RuntimeError ( "Derivative definition of {} in derivatives.yaml illegally " "mixes use of 'grad' and 'grads'. Consider replacing " "occurrences of 'grad' with 'grads[0]'" . format ( defn_name ) ) if only_used_grads_indices and set ( used_grads_indices ) == { 0 } : raise RuntimeError ( "Derivative definition of {} in derivatives.yaml solely " "refers to 'grads[0]'.  If the first output is indeed the " "only differentiable output, replace 'grads[0]' with 'grad'; " "otherwise, there is a likely error in your derivatives " "declaration." . format ( defn_name ) ) hardcoded_diff = HARDCODED_DIFFERENTIABLE_OUTPUTS . get ( defn_name ) if hardcoded_diff : if used_grad : raise RuntimeError ( "Derivative definition {} has hard-coded differentiable " "outputs in gen_autograd.py, but used grad (which implies " "only the first output is differentiable) in its " "derivative declaration.  You likely meant to write " "grads[i] for some i instead." . format ( defn_name ) ) if only_used_grads_indices and set ( used_grads_indices ) != set ( hardcoded_diff ) : raise RuntimeError ( "Derivative definition {} has hard-coded differentiable " "outputs {}, but the used grads in the derivative " "definitions are only {}.  Either your derivatives " "declaration is wrong, or the value of " "HARDCODED_DIFFERENTIABLE_OUTPUTS in gen_autograd.py " "is wrong." . format ( defn_name , hardcoded_diff , used_grads_indices ) ) else : if fully_implemented and not used_grad and used_grads and only_used_grads_indices and set ( used_grads_indices ) != set ( range ( len ( declaration [ 'returns' ] ) ) ) : raise RuntimeError ( "Derivative definition of {} in derivatives.yaml does " "not refer to the gradients of all of its outputs.  Either " "the derivatives declaration is wrong, OR you have some " "non-differentiable outputs.  If you have a single " "differentiable output, make it the first output in ATen " "and reference its gradient with 'grad'; otherwise, hard " "code the list of differentiable outputs in " "HARDCODED_DIFFERENTIABLE_OUTPUTS in gen_autograd.py." . format ( defn_name ) )
Check for some subtle mistakes one might make when writing gradients.
Check for some subtle mistakes one might make when writing gradients .
"""
        Check for some subtle mistakes one might make when writing gradients.
        These mistakes will compile, but will be latent until a function is
        used with double backwards.
        """
defn_name
declaration
derivatives