<commit_before># Copyright 2017 Battelle Energy Alliance, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
  Step size manipulations based on gradient history

  Created 2020-01
  @author: talbpaul
"""
#for future compatibility with Python 3--------------------------------------------------------------
from __future__ import division, print_function, unicode_literals, absolute_import
#End compatibility block for Python 3----------------------------------------------------------------

#External Modules------------------------------------------------------------------------------------
import abc
import numpy as np
#External Modules End--------------------------------------------------------------------------------

#Internal Modules------------------------------------------------------------------------------------
from utils import InputData, InputTypes, mathUtils, randomUtils
from .StepManipulator import StepManipulator
from . import NoConstraintResolutionFound
#Internal Modules End--------------------------------------------------------------------------------

class GradientHistory(StepManipulator):
  """
    Changes step size depending on history of gradients
  """
  requiredInformation = ['gradientHist', 'prevStepSize']
  optionalInformation = ['recommend']

  ##########################
  # Initialization Methods #
  ##########################
  @classmethod
  def getInputSpecification(cls):
    """
      Method to get a reference to a class that specifies the input data for class cls.
      @ In, cls, the class for which we are retrieving the specification
      @ Out, inputSpecification, InputData.ParameterInput, class to use for specifying input of cls.
    """
    specs = super(GradientHistory, cls).getInputSpecification()
    specs.description = r"""if this node is present, indicates that the iterative steps in the gradient
        descent algorithm should be determined by the sequential change in gradient. In particular, rather
        than using the magnitude of the gradient to determine step size, the directional change of the
        gradient versor determines whether to take larger or smaller steps. If the gradient in two successive
        steps changes direction, the step size shrinks. If the gradient instead continues in the same
        direction, the step size grows. The rate of shrink and growth are controlled by the \xmlNode{shrinkFactor}
        and \xmlNode{growthFactor}. Note these values have a large impact on the optimization path taken.
        Large growth factors converge slowly but explore more of the input space; large shrink factors
        converge quickly but might converge before arriving at a local minimum."""
    specs.addSub(InputData.parameterInputFactory('growthFactor', contentType=InputTypes.FloatType,
        descr=r"""specifies the rate at which the step size should grow if the gradient continues in
              same direction through multiple iterative steps. For example, a growth factor of 2 means
              that if the gradient is identical twice, the step size is doubled. \default{1.25} """))
    specs.addSub(InputData.parameterInputFactory('shrinkFactor', contentType=InputTypes.FloatType,
        descr=r"""specifies the rate at which the step size should shrink if the gradient changes
              direction through multiple iterative steps. For example, a shrink factor of 2 means
              that if the gradient completely flips direction, the step size is halved. Note that for
              stochastic surfaces or low-order gradient approximations such as SPSA, a small value
              for the shrink factor is recommended. If an optimization path appears to be converging
              early, increasing the shrink factor might improve the search. \default{1.15} """))
    return specs

  def __init__(self):
    """
      Constructor.
      @ In, None
      @ Out, None
    """
    StepManipulator.__init__(self)
    # TODO
    ## Instance Variable Initialization
    # public
    # _protected
    self._optVars = None         # optimization variables
    self._growth = 1.25          # rate of step growth
    self._shrink = 1.15          # rate of step shrinking
    self._minRotationAngle = 2.0 # how close to perpendicular should we try rotating towards?
    self._numRandomPerp = 10     # how many random perpendiculars should we try rotating towards?
    # __private
    # additional methods

  def handleInput(self, specs):
    """
      Read input specs
      @ In, specs, InputData.ParameterInput, parameter specs interpreted
      @ Out, None
    """
    StepManipulator.handleInput(self, specs)
    growth = specs.findFirst('growthFactor')
    if growth is not None:
      self._growth = growth.value
    shrink = specs.findFirst('shrinkFactor')
    if shrink is not None:
      self._shrink = shrink.value

  def initialize(self, optVars, **kwargs):
    """
      Constructor.
      @ In, None
      @ Out, None
    """
    StepManipulator.initialize(self, optVars, **kwargs)

  ###############
  # Run Methods #
  ###############
  def initialStepSize(self, numOptVars=None, scaling=1.0, **kwargs):
    """
      Provides an initial step size
      @ In, numOptVars, int, number of optimization variables
      @ In, scaling, float, optional, scaling factor
    """
    return mathUtils.hyperdiagonal(np.ones(numOptVars) * scaling) * self._initialStepScaling

  def step(self, prevOpt, gradientHist=None, prevStepSize=None, recommend=None, **kwargs):
    """
      calculates the step size and direction to take
      @ In, prevOpt, dict, previous opt point
      @ In, gradientHist, deque, optional, not used if not provided, list of gradient dictionaries with 0 being oldest; versors
      @ In, prevStepSize, deque, optional, not used if not provieed, list of float step sizes
      @ In, recommend, str, optional, override to 'grow' or 'shrink' step size
      @ In, kwargs, dict, keyword-based specifics as required by individual step sizers
      @ Out, newOpt, dict, new opt point
      @ Out, stepSize, float, new step size
      @ Out, stepInfo, dict, additional information to store about this step
    """
    stepSize = self._stepSize(gradientHist=gradientHist, prevStepSize=prevStepSize,
                              recommend=recommend, **kwargs)
    gradient = gradientHist[-1][1]
    # use gradient, prev point, and step size to choose new point
    newOpt = {}
    for var in self._optVars:
      newOpt[var] = prevOpt[var] - stepSize * gradient[var]
    return newOpt, stepSize, None

  def fixConstraintViolations(self, proposed, previous, fixInfo):
    """
      Given constraint violations, update the desired optimal point to consider.
      @ In, proposed, dict, proposed new optimal point
      @ In, previous, dict, previous optimal point
      @ In, fixInfo, dict, contains record of progress in fixing search
      @ Out, proposed, new proposed point
      @ Out, stepSize, new step size taken # TODO need?
      @ Out, fixInfo, updated fixing info
    """
    # DESIGN
    # While not okay:
    # 1. See if cutting the step will fix it.
    # 2. If not, try rotating towards a random perpendicular. Repeat 1.
    # 3. If not, try a new random perpendicular. Repeat 1. Repeat N times.
    # TODO should this be specific to step manipulators, or something else?
    # TODO updating opt point in place! Is this safe?
    minStepSize = fixInfo['minStepSize']
    stepVector = dict((var, proposed[var] - previous[var]) for var in self._optVars)
    stepDistance, stepDirection, _ = mathUtils.calculateMagnitudeAndVersor(list(stepVector.values()))
    if 'originalStepSize' not in fixInfo:
      fixInfo['originalStepSize'] = stepDistance
    if 'perpDir' in fixInfo:
      perpDir = fixInfo['perpDir']
    # if not done cutting step, start cutting
    if stepDistance > minStepSize:
      # cut step again
      stepSize = 0.5 * stepDistance # TODO user option?
      for v, var in enumerate(stepVector):
        proposed[var] = previous[var] + stepSize * stepDirection[v]
      print(' ... cutting step ...') # norm step to {}, new norm opt {}'.format(stepSize, proposed))
      return proposed, stepSize, fixInfo
    else:
      ### rotate vector and restore full step size
      stepSize = fixInfo['originalStepSize']
      # store original direction
      if 'originalDirection' not in fixInfo:
        fixInfo['originalDirection'] = np.atleast_1d(stepDirection)
      # if this isn't the first time, check if there's angle left to rotate through; reset if not
      if 'perpDir' in fixInfo:
        ang = mathUtils.angleBetweenVectors(stepDirection, fixInfo['perpDir'])
        print(' ... trying angle:', ang)
        if ang < self._minRotationAngle:
          del fixInfo['perpDir']

      if 'perpDir' not in fixInfo:
        # find perpendicular vector
        perp = randomUtils.randomPerpendicularVector(fixInfo['originalDirection'])
        # NOTE we could return to point format, but no reason to
        # normalize perpendicular to versor and resize
        rotations = fixInfo.get('numRotations', 0)
        if rotations > self._numRandomPerp:
          raise NoConstraintResolutionFound
        _, perpDir, _ = mathUtils.calculateMagnitudeAndVersor(perp)
        fixInfo['perpDir'] = perpDir
        fixInfo['numRotations'] = rotations + 1
      # END fixing perpendicular direction
      # rotate vector halfway towards perpendicular
      perpDir = fixInfo['perpDir']

      # rotate towards selected perpendicular
      splitVector = {} # vector that evenly divides stepDirection and perp
      for v, var in enumerate(self._optVars):
        splitVector[var] = stepDirection[v] + perpDir[v]
        #splitVector[var] = - stepDirection[v] + perpDir[v]
      _, splitDir, _ = mathUtils.calculateMagnitudeAndVersor(list(splitVector.values()))
      for v, var in enumerate(self._optVars):
        proposed[var] = previous[var] + stepSize * splitDir[v]
      print(' ... rotating step ...') #ed norm direction to {}, new norm opt {}'.format(splitDir, proposed))
    return proposed, stepSize, fixInfo

  def trajIsFollowing(self, traj, opt, info, dataObject, followers, tolerance):
    """
      Determines if the current trajectory is following another trajectory.
      @ In, traj, int, integer identifier for trajectory that needs to be checked
      @ In, opt, dict, DENORMALIZED most recent optimal point for trajectory
      @ In, info, dict, additional information about optimal point
      @ In, dataObject, DataObject.DataSet, data collected through optimization so far (SolutionExport)
      @ In, followers, list(int), trajectories that are following traj currently
      @ In, tolerance, float, termination distance (in scaled space)
      @ Out, found, int, trajectory that traj is following (or None)
    """
    if followers is None:
      followers = []
    # we define a trajectory as following if its current opt point is sufficiently near other opt
    # points from other trajectories
    matchDict = dict((var, opt[var]) for var in self._optVars)
    # only look in accepted points #TODO would there be value in looking at others?
    matchDict['accepted'] = 'accepted'
    # only look at other trajectories that this trajectory hasn't killed
    noMatchDict = {'trajID': [traj] + followers}

    _, found = dataObject.realization(matchDict=matchDict, noMatchDict=noMatchDict, tol=tolerance)
    if found is not None:
      return found['trajID']
    return None

  ###################
  # Utility Methods #
  ###################
  def _stepSize(self, gradientHist=None, prevStepSize=None, recommend=None, **kwargs):
    """
      Calculates a new step size to use in the optimization path.
      @ In, gradientHist, deque, list of gradient dictionaries with 0 being oldest; versors
      @ In, prevStepSize, deque, list of float step sizes
      @ In, recommend, str, optional, override to 'grow' or 'shrink' step size
      @ In, kwargs, dict, keyword-based specifics as required by individual step sizers
      @ Out, stepSize, float, new step size
    """
    # grad0 = gradientHist[-1][1]
    # grad1 = gradientHist[-2][1] if len(gradientHist) > 1 else None
    # FIXME try using the step directions instead
    step0 = prevStepSize[-1]['versor']
    if step0 is None:
      step0 = gradientHist[-1][1]
    step1 = prevStepSize[-2]['versor'] if len(prevStepSize) > 1 else None
    gainFactor = self._fractionalStepChange(step0, step1, recommend=recommend)
    # gainFactor = self._fractionalStepChange(grad0, grad1, recommend=recommend)
    stepSize = gainFactor * prevStepSize[-1]['magnitude']
    return stepSize

  def _fractionalStepChange(self, grad0, grad1, recommend=None):
    """
      Calculates fractional step change based on gradient history
      @ In, grad0, dict, most recent gradient direction (versor)
      @ In, grad1, dict, next recent gradient direction (versor)
      @ In, recommend, str, optional, can override gradient-based suggestion to either cut or grow
      @ Out, factor, multiplicitave factor to use on step size
    """
    assert grad0 is not None
    # grad1 can be None if only one point has been taken
    assert recommend in [None, 'shrink', 'grow']
    if recommend:
      if recommend == 'shrink':
        factor = 1. / self._shrink
      else:
        factor = self._growth
      return factor
    # if history is only a single gradient, then keep step size the same for now
    if grad1 is None:
      return 1.0
    # otherwise, figure it out based on the gradient history
    # scalar product
    prod = np.dot(grad0, grad1)
    # prod = np.sum([np.sum(grad0 * grad1) for v in grad0.keys()])
    if prod > 0:
      factor = self._growth ** prod
    else:
      # NOTE prod is negative, so this is like 1 / (shrink ^ abs(prod))
      factor = self._shrink ** prod
    return factor

<commit_msg>missed file<commit_after># Copyright 2017 Battelle Energy Alliance, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
  Step size manipulations based on gradient history

  Created 2020-01
  @author: talbpaul
"""
#for future compatibility with Python 3--------------------------------------------------------------
from __future__ import division, print_function, unicode_literals, absolute_import
#End compatibility block for Python 3----------------------------------------------------------------

#External Modules------------------------------------------------------------------------------------
import abc
import numpy as np
#External Modules End--------------------------------------------------------------------------------

#Internal Modules------------------------------------------------------------------------------------
from utils import InputData, InputTypes, mathUtils, randomUtils
from .StepManipulator import StepManipulator
from . import NoConstraintResolutionFound
#Internal Modules End--------------------------------------------------------------------------------

class GradientHistory(StepManipulator):
  """
    Changes step size depending on history of gradients
  """
  requiredInformation = ['gradientHist', 'prevStepSize']
  optionalInformation = ['recommend']

  ##########################
  # Initialization Methods #
  ##########################
  @classmethod
  def getInputSpecification(cls):
    """
      Method to get a reference to a class that specifies the input data for class cls.
      @ In, cls, the class for which we are retrieving the specification
      @ Out, inputSpecification, InputData.ParameterInput, class to use for specifying input of cls.
    """
    specs = super(GradientHistory, cls).getInputSpecification()
    specs.description = r"""if this node is present, indicates that the iterative steps in the gradient
        descent algorithm should be determined by the sequential change in gradient. In particular, rather
        than using the magnitude of the gradient to determine step size, the directional change of the
        gradient versor determines whether to take larger or smaller steps. If the gradient in two successive
        steps changes direction, the step size shrinks. If the gradient instead continues in the same
        direction, the step size grows. The rate of shrink and growth are controlled by the \xmlNode{shrinkFactor}
        and \xmlNode{growthFactor}. Note these values have a large impact on the optimization path taken.
        Large growth factors converge slowly but explore more of the input space; large shrink factors
        converge quickly but might converge before arriving at a local minimum."""
    specs.addSub(InputData.parameterInputFactory('growthFactor', contentType=InputTypes.FloatType,
        descr=r"""specifies the rate at which the step size should grow if the gradient continues in
              same direction through multiple iterative steps. For example, a growth factor of 2 means
              that if the gradient is identical twice, the step size is doubled. \default{1.25} """))
    specs.addSub(InputData.parameterInputFactory('shrinkFactor', contentType=InputTypes.FloatType,
        descr=r"""specifies the rate at which the step size should shrink if the gradient changes
              direction through multiple iterative steps. For example, a shrink factor of 2 means
              that if the gradient completely flips direction, the step size is halved. Note that for
              stochastic surfaces or low-order gradient approximations such as SPSA, a small value
              for the shrink factor is recommended. If an optimization path appears to be converging
              early, increasing the shrink factor might improve the search. \default{1.15} """))
    specs.addSub(InputData.parameterInputFactory('terms', contentType=InputTypes.IntegerType,
        descr=r"""the number of previous gradient evaluations to include when determining a new step
              direction. Modifying this allows past gradient evaluations to influence future steps,
              with a decaying influence. Setting this to 1 means only the local gradient evaluation
              will be used. \default{1}."""))
    specs.addSub(InputData.parameterInputFactory('decay', contentType=InputTypes.FloatType,
        descr=r"""if including more than one gradient history terms when determining a new step direction,
              specifies the rate of decay for previous terms to influence the current direction. The
              decay factor has the form $e^(-\lambda t)$, where $t$ counts the gradient terms starting with
              the most recent as 0 and moving towards the past, and $\lamda$ is this decay factor.
              This should generally be a small decimal number. \default{0.2}"""))
    return specs

  def __init__(self):
    """
      Constructor.
      @ In, None
      @ Out, None
    """
    StepManipulator.__init__(self)
    # TODO
    ## Instance Variable Initialization
    # public
    # _protected
    self._optVars = None         # optimization variables
    self._growth = 1.25          # rate of step growth
    self._shrink = 1.15          # rate of step shrinking
    self._gradTerms = 1          # number of historical gradients to use, if available
    self._termDecay = 0.2        # rate at which historical gradients drop off
    self._minRotationAngle = 2.0 # how close to perpendicular should we try rotating towards?
    self._numRandomPerp = 10     # how many random perpendiculars should we try rotating towards?
    # __private
    # additional methods

  def handleInput(self, specs):
    """
      Read input specs
      @ In, specs, InputData.ParameterInput, parameter specs interpreted
      @ Out, None
    """
    StepManipulator.handleInput(self, specs)
    growth = specs.findFirst('growthFactor')
    if growth is not None:
      self._growth = growth.value
    shrink = specs.findFirst('shrinkFactor')
    if shrink is not None:
      self._shrink = shrink.value
    gradTerms = specs.findFirst('terms')
    if gradTerms is not None:
      self._gradTerms = gradTerms.value
    termDecay = specs.findFirst('decay')
    if termDecay is not None:
      self._termDecay = termDecay.value

  def initialize(self, optVars, **kwargs):
    """
      Constructor.
      @ In, None
      @ Out, None
    """
    StepManipulator.initialize(self, optVars, **kwargs)

  ###############
  # Run Methods #
  ###############
  def initialStepSize(self, numOptVars=None, scaling=1.0, **kwargs):
    """
      Provides an initial step size
      @ In, numOptVars, int, number of optimization variables
      @ In, scaling, float, optional, scaling factor
    """
    return mathUtils.hyperdiagonal(np.ones(numOptVars) * scaling) * self._initialStepScaling

  def step(self, prevOpt, gradientHist=None, prevStepSize=None, recommend=None, **kwargs):
    """
      calculates the step size and direction to take
      @ In, prevOpt, dict, previous opt point
      @ In, gradientHist, deque, optional, not used if not provided, list of gradient dictionaries with 0 being oldest; versors
      @ In, prevStepSize, deque, optional, not used if not provieed, list of float step sizes
      @ In, recommend, str, optional, override to 'grow' or 'shrink' step size
      @ In, kwargs, dict, keyword-based specifics as required by individual step sizers
      @ Out, newOpt, dict, new opt point
      @ Out, stepSize, float, new step size
      @ Out, stepInfo, dict, additional information to store about this step
    """
    stepSize = self._stepSize(gradientHist=gradientHist, prevStepSize=prevStepSize,
                              recommend=recommend, **kwargs)
    direction = dict((var, 0) for var in self._optVars)
    for t in range(self._gradTerms):
      if len(gradientHist) <= t:
        break
      decay = np.exp(-t * self._termDecay)
      for var in direction:
        direction[var] -= gradientHist[-(t+1)][1][var] * decay
    # gradient = gradientHist[-1][1]
    # use gradient, prev point, and step size to choose new point
    newOpt = {}
    for var in self._optVars:
      newOpt[var] = prevOpt[var] + stepSize * direction[var]
    return newOpt, stepSize, None

  def fixConstraintViolations(self, proposed, previous, fixInfo):
    """
      Given constraint violations, update the desired optimal point to consider.
      @ In, proposed, dict, proposed new optimal point
      @ In, previous, dict, previous optimal point
      @ In, fixInfo, dict, contains record of progress in fixing search
      @ Out, proposed, new proposed point
      @ Out, stepSize, new step size taken # TODO need?
      @ Out, fixInfo, updated fixing info
    """
    # DESIGN
    # While not okay:
    # 1. See if cutting the step will fix it.
    # 2. If not, try rotating towards a random perpendicular. Repeat 1.
    # 3. If not, try a new random perpendicular. Repeat 1. Repeat N times.
    # TODO should this be specific to step manipulators, or something else?
    # TODO updating opt point in place! Is this safe?
    minStepSize = fixInfo['minStepSize']
    stepVector = dict((var, proposed[var] - previous[var]) for var in self._optVars)
    stepDistance, stepDirection, _ = mathUtils.calculateMagnitudeAndVersor(list(stepVector.values()))
    if 'originalStepSize' not in fixInfo:
      fixInfo['originalStepSize'] = stepDistance
    if 'perpDir' in fixInfo:
      perpDir = fixInfo['perpDir']
    # if not done cutting step, start cutting
    if stepDistance > minStepSize:
      # cut step again
      stepSize = 0.5 * stepDistance # TODO user option?
      for v, var in enumerate(stepVector):
        proposed[var] = previous[var] + stepSize * stepDirection[v]
      print(' ... cutting step ...') # norm step to {}, new norm opt {}'.format(stepSize, proposed))
      return proposed, stepSize, fixInfo
    else:
      ### rotate vector and restore full step size
      stepSize = fixInfo['originalStepSize']
      # store original direction
      if 'originalDirection' not in fixInfo:
        fixInfo['originalDirection'] = np.atleast_1d(stepDirection)
      # if this isn't the first time, check if there's angle left to rotate through; reset if not
      if 'perpDir' in fixInfo:
        ang = mathUtils.angleBetweenVectors(stepDirection, fixInfo['perpDir'])
        print(' ... trying angle:', ang)
        if ang < self._minRotationAngle:
          del fixInfo['perpDir']

      if 'perpDir' not in fixInfo:
        # find perpendicular vector
        perp = randomUtils.randomPerpendicularVector(fixInfo['originalDirection'])
        # NOTE we could return to point format, but no reason to
        # normalize perpendicular to versor and resize
        rotations = fixInfo.get('numRotations', 0)
        if rotations > self._numRandomPerp:
          raise NoConstraintResolutionFound
        _, perpDir, _ = mathUtils.calculateMagnitudeAndVersor(perp)
        fixInfo['perpDir'] = perpDir
        fixInfo['numRotations'] = rotations + 1
      # END fixing perpendicular direction
      # rotate vector halfway towards perpendicular
      perpDir = fixInfo['perpDir']

      # rotate towards selected perpendicular
      splitVector = {} # vector that evenly divides stepDirection and perp
      for v, var in enumerate(self._optVars):
        splitVector[var] = stepDirection[v] + perpDir[v]
        #splitVector[var] = - stepDirection[v] + perpDir[v]
      _, splitDir, _ = mathUtils.calculateMagnitudeAndVersor(list(splitVector.values()))
      for v, var in enumerate(self._optVars):
        proposed[var] = previous[var] + stepSize * splitDir[v]
      print(' ... rotating step ...') #ed norm direction to {}, new norm opt {}'.format(splitDir, proposed))
    return proposed, stepSize, fixInfo

  def trajIsFollowing(self, traj, opt, info, dataObject, followers, tolerance):
    """
      Determines if the current trajectory is following another trajectory.
      @ In, traj, int, integer identifier for trajectory that needs to be checked
      @ In, opt, dict, DENORMALIZED most recent optimal point for trajectory
      @ In, info, dict, additional information about optimal point
      @ In, dataObject, DataObject.DataSet, data collected through optimization so far (SolutionExport)
      @ In, followers, list(int), trajectories that are following traj currently
      @ In, tolerance, float, termination distance (in scaled space)
      @ Out, found, int, trajectory that traj is following (or None)
    """
    if followers is None:
      followers = []
    # we define a trajectory as following if its current opt point is sufficiently near other opt
    # points from other trajectories
    matchDict = dict((var, opt[var]) for var in self._optVars)
    # only look in accepted points #TODO would there be value in looking at others?
    matchDict['accepted'] = 'accepted'
    # only look at other trajectories that this trajectory hasn't killed
    noMatchDict = {'trajID': [traj] + followers}

    _, found = dataObject.realization(matchDict=matchDict, noMatchDict=noMatchDict, tol=tolerance)
    if found is not None:
      return found['trajID']
    return None

  ###################
  # Utility Methods #
  ###################
  def _stepSize(self, gradientHist=None, prevStepSize=None, recommend=None, **kwargs):
    """
      Calculates a new step size to use in the optimization path.
      @ In, gradientHist, deque, list of gradient dictionaries with 0 being oldest; versors
      @ In, prevStepSize, deque, list of float step sizes
      @ In, recommend, str, optional, override to 'grow' or 'shrink' step size
      @ In, kwargs, dict, keyword-based specifics as required by individual step sizers
      @ Out, stepSize, float, new step size
    """
    # grad0 = gradientHist[-1][1]
    # grad1 = gradientHist[-2][1] if len(gradientHist) > 1 else None
    # FIXME try using the step directions instead
    step0 = prevStepSize[-1]['versor']
    if step0 is None:
      step0 = gradientHist[-1][1]
    step1 = prevStepSize[-2]['versor'] if len(prevStepSize) > 1 else None
    gainFactor = self._fractionalStepChange(step0, step1, recommend=recommend)
    # gainFactor = self._fractionalStepChange(grad0, grad1, recommend=recommend)
    stepSize = gainFactor * prevStepSize[-1]['magnitude']
    return stepSize

  def _fractionalStepChange(self, grad0, grad1, recommend=None):
    """
      Calculates fractional step change based on gradient history
      @ In, grad0, dict, most recent gradient direction (versor)
      @ In, grad1, dict, next recent gradient direction (versor)
      @ In, recommend, str, optional, can override gradient-based suggestion to either cut or grow
      @ Out, factor, multiplicitave factor to use on step size
    """
    assert grad0 is not None
    # grad1 can be None if only one point has been taken
    assert recommend in [None, 'shrink', 'grow']
    if recommend:
      if recommend == 'shrink':
        factor = 1. / self._shrink
      else:
        factor = self._growth
      return factor
    # if history is only a single gradient, then keep step size the same for now
    if grad1 is None:
      return 1.0
    # otherwise, figure it out based on the gradient history
    # scalar product
    prod = np.dot(grad0, grad1)
    # prod = np.sum([np.sum(grad0 * grad1) for v in grad0.keys()])
    if prod > 0:
      factor = self._growth ** prod
    else:
      # NOTE prod is negative, so this is like 1 / (shrink ^ abs(prod))
      factor = self._shrink ** prod
    return factor

<|endoftext|>


<commit_before># Edge Detection Example:
#
# This example demonstrates using the morph function on an image to do edge
# detection and then thresholding and filtering that image afterwards.

import sensor, image, time

kernel_size = 1 # kernel width = (size*2)+1, kernel height = (size*2)+1
kernel = [-1, -1, -1,\
          -1, +8, -1,\
          -1, -1, -1]
# This is a high pass filter kernel. see here for more kernels:
# http://www.fmwconcepts.com/imagemagick/digital_image_filtering.pdf
thresholds = [(100, 255)] # grayscale thresholds

sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.GRAYSCALE) # or sensor.RGB565
sensor.set_framesize(sensor.QQVGA) # or sensor.QVGA (or others)
sensor.skip_frames(10) # Let new settings take affect.
clock = time.clock() # Tracks FPS.

while(True):
    clock.tick() # Track elapsed milliseconds between snapshots().
    img = sensor.snapshot() # Take a picture and return the image.

    img.morph(kernel_size, kernel)
    img.binary(thresholds)

    # Erode pixels with less than 2 neighbors using a 3x3 image kernel
    img.erode(1, threshold = 2)

    print(clock.fps()) # Note: Your OpenMV Cam runs about half as fast while
    # connected to your computer. The FPS should increase once disconnected.
<commit_msg>Set sharpness on OV7725 for edge detection.<commit_after># Edge Detection Example:
#
# This example demonstrates using the morph function on an image to do edge
# detection and then thresholding and filtering that image afterwards.

import sensor, image, time

kernel_size = 1 # kernel width = (size*2)+1, kernel height = (size*2)+1
kernel = [-1, -1, -1,\
          -1, +8, -1,\
          -1, -1, -1]
# This is a high pass filter kernel. see here for more kernels:
# http://www.fmwconcepts.com/imagemagick/digital_image_filtering.pdf
thresholds = [(100, 255)] # grayscale thresholds

sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.GRAYSCALE) # or sensor.RGB565
sensor.set_framesize(sensor.QQVGA) # or sensor.QVGA (or others)
sensor.skip_frames(10) # Let new settings take affect.
clock = time.clock() # Tracks FPS.

# On the OV7725 sensor, edge detection can be enhanced
# significantly by setting the sharpness/edge registers.
# Note: This will be implemented as a function later.
if (sensor.get_id() == sensor.OV7725):
    sensor.__write_reg(0xAC, 0xDF)
    sensor.__write_reg(0x8F, 0xFF)

while(True):
    clock.tick() # Track elapsed milliseconds between snapshots().
    img = sensor.snapshot() # Take a picture and return the image.

    img.morph(kernel_size, kernel)
    img.binary(thresholds)

    # Erode pixels with less than 2 neighbors using a 3x3 image kernel
    img.erode(1, threshold = 2)

    print(clock.fps()) # Note: Your OpenMV Cam runs about half as fast while
    # connected to your computer. The FPS should increase once disconnected.
<|endoftext|>


<commit_before># Copyright 2013-2019 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *

class Cdo(AutotoolsPackage):
    """CDO is a collection of command line Operators to manipulate and analyse
       Climate and NWP model Data.
    """

    homepage = 'https://code.mpimet.mpg.de/projects/cdo'
    url = 'https://code.mpimet.mpg.de/attachments/download/12760/cdo-1.7.2.tar.gz'
    list_url = 'https://code.mpimet.mpg.de/projects/cdo/files'

    maintainers = ['skosukhin']

    version('1.9.7.1', sha256='3771952e065bcf935d43e492707370ed2a0ecb59a06bea24f9ab69d77943962c',
            url='https://code.mpimet.mpg.de/attachments/download/20124/cdo-1.9.7.1.tar.gz')
    version('1.9.6', sha256='b31474c94548d21393758caa33f35cf7f423d5dfc84562ad80a2bdcb725b5585', url='https://code.mpimet.mpg.de/attachments/download/19299/cdo-1.9.6.tar.gz')
    version('1.9.5', sha256='48ed65cc5b436753c8e7f9eadd8aa97376698ce230ceafed2a4350a5b1a27148', url='https://code.mpimet.mpg.de/attachments/download/18264/cdo-1.9.5.tar.gz')
    version('1.9.4', sha256='3d1c0fd3f7d38c5d3d88139ca1546c9d24e1b1ff752a794a4194dfe624695def', url='https://code.mpimet.mpg.de/attachments/download/17374/cdo-1.9.4.tar.gz')
    version('1.9.3', sha256='e83a3de7b402600c0d9a5df18073d36d133ff9719d3c561a0efa90f9c1599f3f', url='https://code.mpimet.mpg.de/attachments/download/16435/cdo-1.9.3.tar.gz')
    version('1.9.2', sha256='d1c5092167034a48e4b8ada24cf78a1d4b84e364ffbb08b9ca70d13f428f300c', url='https://code.mpimet.mpg.de/attachments/download/16035/cdo-1.9.2.tar.gz')
    version('1.9.1', sha256='33cba3cfcc27e5896769143c5f8e2f300ca14c7a40d1f19ffd1ed24b49ea3d55', url='https://code.mpimet.mpg.de/attachments/download/15653/cdo-1.9.1.tar.gz')
    version('1.9.0', sha256='df367f8c3abf4ab085bcfc61e0205b28a5ecc69b7b83ba398b4d3c874dd69008', url='https://code.mpimet.mpg.de/attachments/download/15187/cdo-1.9.0.tar.gz')
    version('1.8.2', sha256='6ca6c1263af2237737728ac937a275f8aa27680507636a6b6320f347c69a369a', url='https://code.mpimet.mpg.de/attachments/download/14686/cdo-1.8.2.tar.gz')
    version('1.7.2', sha256='4c43eba7a95f77457bfe0d30fb82382b3b5f2b0cf90aca6f0f0a008f6cc7e697', url='https://code.mpimet.mpg.de/attachments/download/12760/cdo-1.7.2.tar.gz')

    variant('netcdf', default=True, description='Enable NetCDF support')
    variant('grib2', default='eccodes', values=('eccodes', 'grib-api', 'none'),
            description='Specify GRIB2 backend')
    variant('external-grib1', default=False,
            description='Ignore the built-in support and use the external '
                        'GRIB2 backend for GRIB1 files')
    variant('szip', default=True,
            description='Enable szip compression for GRIB1')
    variant('hdf5', default=True, description='Enable HDF5 support')

    variant('udunits2', default=True, description='Enable UDUNITS2 support')
    variant('libxml2', default=True, description='Enable libxml2 support')
    variant('proj', default=True,
            description='Enable PROJ library for cartographic projections')
    variant('curl', default=False, description='Enable curl support')
    variant('fftw3', default=True, description='Enable support for fftw3')
    variant('magics', default=False,
            description='Enable Magics library support')
    variant('openmp', default=True, description='Enable OpenMP support')

    depends_on('pkgconfig', type='build')

    depends_on('netcdf-c', when='+netcdf')
    # In this case CDO does not depend on hdf5 directly but we need the backend
    # of netcdf to be thread safe.
    depends_on('hdf5+threadsafe', when='+netcdf')

    depends_on('grib-api', when='grib2=grib-api')
    depends_on('eccodes', when='grib2=eccodes')

    depends_on('szip', when='+szip')

    depends_on('hdf5+threadsafe', when='+hdf5')

    depends_on('udunits', when='+udunits2')
    depends_on('libxml2', when='+libxml2')
    depends_on('proj@:5', when='+proj')
    depends_on('curl', when='+curl')
    depends_on('fftw@3:', when='+fftw3')
    depends_on('magics', when='+magics')
    depends_on('libuuid')

    conflicts('grib2=eccodes', when='@:1.8',
              msg='Eccodes is supported starting version 1.9.0')
    conflicts('+szip', when='+external-grib1 grib2=none',
              msg='The configuration does not support GRIB1')
    conflicts('%gcc@9:', when='@:1.9.6',
              msg='GCC 9 changed OpenMP data sharing behavior')

    def configure_args(self):
        config_args = self.with_or_without('netcdf', activation_value='prefix')

        if self.spec.variants['grib2'].value == 'eccodes':
            config_args.append('--with-eccodes=' +
                               self.spec['eccodes'].prefix)
            config_args.append('--without-grib_api')
        elif self.spec.variants['grib2'].value == 'grib-api':
            config_args.append('--with-grib_api=' +
                               self.spec['grib-api'].prefix)
            if self.spec.satisfies('@1.9:'):
                config_args.append('--without-eccodes')
        else:
            config_args.append('--without-grib_api')
            if self.spec.satisfies('@1.9:'):
                config_args.append('--without-eccodes')

        if '+external-grib1' in self.spec:
            config_args.append('--disable-cgribex')
        else:
            config_args.append('--enable-cgribex')

        if '+szip' in self.spec:
            config_args.append('--with-szlib=' + self.spec['szip'].prefix)
        else:
            config_args.append('--without-szlib')

        config_args += self.with_or_without('hdf5',
                                            activation_value='prefix')

        config_args += self.with_or_without('udunits2',
                                            activation_value='prefix')

        config_args += self.with_or_without('libxml2',
                                            activation_value='prefix')

        config_args += self.with_or_without('proj',
                                            activation_value='prefix')

        config_args += self.with_or_without('curl',
                                            activation_value='prefix')

        config_args += self.with_or_without('magics',
                                            activation_value='prefix')

        config_args += self.with_or_without('fftw3')

        config_args += self.enable_or_disable('openmp')

        # Starting version 1.9.0 CDO is a C++ program but it uses the C
        # interface of HDF5 without the parallel features. To avoid
        # unnecessary dependencies on mpi's cxx library, we need to set the
        # following flags. This works for OpenMPI, MPICH, MVAPICH, Intel MPI,
        # IBM Spectrum MPI, bullx MPI, and Cray MPI.
        if self.spec.satisfies('@1.9:+hdf5^hdf5+mpi'):
            config_args.append(
                'CPPFLAGS=-DOMPI_SKIP_MPICXX -DMPICH_SKIP_MPICXX')

        return config_args
<commit_msg>cdo: Fix with_or_without calls (#13614)<commit_after># Copyright 2013-2019 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *

class Cdo(AutotoolsPackage):
    """CDO is a collection of command line Operators to manipulate and analyse
       Climate and NWP model Data.
    """

    homepage = 'https://code.mpimet.mpg.de/projects/cdo'
    url = 'https://code.mpimet.mpg.de/attachments/download/12760/cdo-1.7.2.tar.gz'
    list_url = 'https://code.mpimet.mpg.de/projects/cdo/files'

    maintainers = ['skosukhin']

    version('1.9.7.1', sha256='3771952e065bcf935d43e492707370ed2a0ecb59a06bea24f9ab69d77943962c',
            url='https://code.mpimet.mpg.de/attachments/download/20124/cdo-1.9.7.1.tar.gz')
    version('1.9.6', sha256='b31474c94548d21393758caa33f35cf7f423d5dfc84562ad80a2bdcb725b5585', url='https://code.mpimet.mpg.de/attachments/download/19299/cdo-1.9.6.tar.gz')
    version('1.9.5', sha256='48ed65cc5b436753c8e7f9eadd8aa97376698ce230ceafed2a4350a5b1a27148', url='https://code.mpimet.mpg.de/attachments/download/18264/cdo-1.9.5.tar.gz')
    version('1.9.4', sha256='3d1c0fd3f7d38c5d3d88139ca1546c9d24e1b1ff752a794a4194dfe624695def', url='https://code.mpimet.mpg.de/attachments/download/17374/cdo-1.9.4.tar.gz')
    version('1.9.3', sha256='e83a3de7b402600c0d9a5df18073d36d133ff9719d3c561a0efa90f9c1599f3f', url='https://code.mpimet.mpg.de/attachments/download/16435/cdo-1.9.3.tar.gz')
    version('1.9.2', sha256='d1c5092167034a48e4b8ada24cf78a1d4b84e364ffbb08b9ca70d13f428f300c', url='https://code.mpimet.mpg.de/attachments/download/16035/cdo-1.9.2.tar.gz')
    version('1.9.1', sha256='33cba3cfcc27e5896769143c5f8e2f300ca14c7a40d1f19ffd1ed24b49ea3d55', url='https://code.mpimet.mpg.de/attachments/download/15653/cdo-1.9.1.tar.gz')
    version('1.9.0', sha256='df367f8c3abf4ab085bcfc61e0205b28a5ecc69b7b83ba398b4d3c874dd69008', url='https://code.mpimet.mpg.de/attachments/download/15187/cdo-1.9.0.tar.gz')
    version('1.8.2', sha256='6ca6c1263af2237737728ac937a275f8aa27680507636a6b6320f347c69a369a', url='https://code.mpimet.mpg.de/attachments/download/14686/cdo-1.8.2.tar.gz')
    version('1.7.2', sha256='4c43eba7a95f77457bfe0d30fb82382b3b5f2b0cf90aca6f0f0a008f6cc7e697', url='https://code.mpimet.mpg.de/attachments/download/12760/cdo-1.7.2.tar.gz')

    variant('netcdf', default=True, description='Enable NetCDF support')
    variant('grib2', default='eccodes', values=('eccodes', 'grib-api', 'none'),
            description='Specify GRIB2 backend')
    variant('external-grib1', default=False,
            description='Ignore the built-in support and use the external '
                        'GRIB2 backend for GRIB1 files')
    variant('szip', default=True,
            description='Enable szip compression for GRIB1')
    variant('hdf5', default=True, description='Enable HDF5 support')

    variant('udunits2', default=True, description='Enable UDUNITS2 support')
    variant('libxml2', default=True, description='Enable libxml2 support')
    variant('proj', default=True,
            description='Enable PROJ library for cartographic projections')
    variant('curl', default=False, description='Enable curl support')
    variant('fftw3', default=True, description='Enable support for fftw3')
    variant('magics', default=False,
            description='Enable Magics library support')
    variant('openmp', default=True, description='Enable OpenMP support')

    depends_on('pkgconfig', type='build')

    depends_on('netcdf-c', when='+netcdf')
    # In this case CDO does not depend on hdf5 directly but we need the backend
    # of netcdf to be thread safe.
    depends_on('hdf5+threadsafe', when='+netcdf')

    depends_on('grib-api', when='grib2=grib-api')
    depends_on('eccodes', when='grib2=eccodes')

    depends_on('szip', when='+szip')

    depends_on('hdf5+threadsafe', when='+hdf5')

    depends_on('udunits', when='+udunits2')
    depends_on('libxml2', when='+libxml2')
    depends_on('proj@:5', when='+proj')
    depends_on('curl', when='+curl')
    depends_on('fftw@3:', when='+fftw3')
    depends_on('magics', when='+magics')
    depends_on('libuuid')

    conflicts('grib2=eccodes', when='@:1.8',
              msg='Eccodes is supported starting version 1.9.0')
    conflicts('+szip', when='+external-grib1 grib2=none',
              msg='The configuration does not support GRIB1')
    conflicts('%gcc@9:', when='@:1.9.6',
              msg='GCC 9 changed OpenMP data sharing behavior')

    def configure_args(self):
        config_args = self.with_or_without(
            'netcdf',
            activation_value=lambda x: self.spec['netcdf-c'].prefix)

        if self.spec.variants['grib2'].value == 'eccodes':
            config_args.append('--with-eccodes=' +
                               self.spec['eccodes'].prefix)
            config_args.append('--without-grib_api')
        elif self.spec.variants['grib2'].value == 'grib-api':
            config_args.append('--with-grib_api=' +
                               self.spec['grib-api'].prefix)
            if self.spec.satisfies('@1.9:'):
                config_args.append('--without-eccodes')
        else:
            config_args.append('--without-grib_api')
            if self.spec.satisfies('@1.9:'):
                config_args.append('--without-eccodes')

        if '+external-grib1' in self.spec:
            config_args.append('--disable-cgribex')
        else:
            config_args.append('--enable-cgribex')

        if '+szip' in self.spec:
            config_args.append('--with-szlib=' + self.spec['szip'].prefix)
        else:
            config_args.append('--without-szlib')

        config_args += self.with_or_without('hdf5',
                                            activation_value='prefix')

        config_args += self.with_or_without(
            'udunits2',
            activation_value=lambda x: self.spec['udunits'].prefix)

        config_args += self.with_or_without('libxml2',
                                            activation_value='prefix')

        config_args += self.with_or_without('proj',
                                            activation_value='prefix')

        config_args += self.with_or_without('curl',
                                            activation_value='prefix')

        config_args += self.with_or_without('magics',
                                            activation_value='prefix')

        config_args += self.with_or_without('fftw3')

        config_args += self.enable_or_disable('openmp')

        # Starting version 1.9.0 CDO is a C++ program but it uses the C
        # interface of HDF5 without the parallel features. To avoid
        # unnecessary dependencies on mpi's cxx library, we need to set the
        # following flags. This works for OpenMPI, MPICH, MVAPICH, Intel MPI,
        # IBM Spectrum MPI, bullx MPI, and Cray MPI.
        if self.spec.satisfies('@1.9:+hdf5^hdf5+mpi'):
            config_args.append(
                'CPPFLAGS=-DOMPI_SKIP_MPICXX -DMPICH_SKIP_MPICXX')

        return config_args
<|endoftext|>


<commit_before>"""
Django settings for growth_studio project.

Generated by 'django-admin startproject' using Django 1.10.2.

For more information on this file, see
https://docs.djangoproject.com/en/1.10/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.10/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'q2c4xbdh)hf-$z7v1dyai3n^+(g%l5ogi17rm+rud^ysbx-(h0'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = [
    '127.0.0.1',
    'localhost',
    'growth.studio.ren'
]

X_FRAME_OPTIONS = 'DENY'

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'corsheaders',
    'homepage',
    'blog',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
]

ROOT_URLCONF = 'growth_studio.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ['templates/'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'growth_studio.wsgi.application'

# Password validation
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/

LANGUAGE_CODE = 'en'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/

STATIC_URL = '/static/'

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static/'),
)
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')

### settings.py file
### settings that are not environment dependent
try:
    from .local_settings import *
except ImportError:
    pass

CORS_ALLOW_CREDENTIALS = True

CORS_ORIGIN_WHITELIST = (
    'studio.growth.ren',
    'localhost:8100',
    '127.0.0.1:8100'
)
<commit_msg>remove allow credentials<commit_after>"""
Django settings for growth_studio project.

Generated by 'django-admin startproject' using Django 1.10.2.

For more information on this file, see
https://docs.djangoproject.com/en/1.10/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.10/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'q2c4xbdh)hf-$z7v1dyai3n^+(g%l5ogi17rm+rud^ysbx-(h0'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = [
    '127.0.0.1',
    'localhost',
    'growth.studio.ren'
]

X_FRAME_OPTIONS = 'DENY'

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'corsheaders',
    'homepage',
    'blog',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
]

ROOT_URLCONF = 'growth_studio.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ['templates/'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'growth_studio.wsgi.application'

# Password validation
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/

LANGUAGE_CODE = 'en'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/

STATIC_URL = '/static/'

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static/'),
)
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')

### settings.py file
### settings that are not environment dependent
try:
    from .local_settings import *
except ImportError:
    pass

CORS_ORIGIN_WHITELIST = (
    'studio.growth.ren',
    'localhost:8100',
    '127.0.0.1:8100'
)
<|endoftext|>


<commit_before># Copyright 2013-2019 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *

class Ior(AutotoolsPackage):
    """The IOR software is used for benchmarking parallel file systems
    using POSIX, MPI-IO, or HDF5 interfaces."""

    homepage = "https://github.com/hpc/ior"
    url      = "https://github.com/hpc/ior/archive/3.2.0.tar.gz"

    version('3.2.0',    sha256='0cda0e00b7f070c6754ef8acb3873eb3a625bd8dee3f2e220291656be1322bbb')
    version('3.0.1', '71150025e0bb6ea1761150f48b553065')

    variant('hdf5',  default=False, description='support IO with HDF5 backend')
    variant('ncmpi', default=False, description='support IO with NCMPI backend')

    depends_on('autoconf', type='build')
    depends_on('automake', type='build')
    depends_on('libtool', type='build')
    depends_on('m4', type='build')
    depends_on('mpi')
    depends_on('hdf5+mpi', when='+hdf5')
    depends_on('parallel-netcdf', when='+ncmpi')

    @run_before('autoreconf')
    def bootstrap(self):
        Executable('./bootstrap')()

    def configure_args(self):
        spec = self.spec
        config_args = []

        env['CC'] = spec['mpi'].mpicc

        if '+hdf5' in spec:
            config_args.append('--with-hdf5')
            config_args.append('CFLAGS=-D H5_USE_16_API')
        else:
            config_args.append('--without-hdf5')

        if '+ncmpi' in spec:
            config_args.append('--with-ncmpi')
        else:
            config_args.append('--without-ncmpi')

        return config_args
<commit_msg>Fix sha256 sum for IOR (#10765)<commit_after># Copyright 2013-2019 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *

class Ior(AutotoolsPackage):
    """The IOR software is used for benchmarking parallel file systems
    using POSIX, MPI-IO, or HDF5 interfaces."""

    homepage = "https://github.com/hpc/ior"
    url      = "https://github.com/hpc/ior/archive/3.2.0.tar.gz"

    version('3.2.0',    sha256='91a766fb9c34b5780705d0997b71b236a1120da46652763ba11d9a8c44251852')
    version('3.0.1', '71150025e0bb6ea1761150f48b553065')

    variant('hdf5',  default=False, description='support IO with HDF5 backend')
    variant('ncmpi', default=False, description='support IO with NCMPI backend')

    depends_on('autoconf', type='build')
    depends_on('automake', type='build')
    depends_on('libtool', type='build')
    depends_on('m4', type='build')
    depends_on('mpi')
    depends_on('hdf5+mpi', when='+hdf5')
    depends_on('parallel-netcdf', when='+ncmpi')

    @run_before('autoreconf')
    def bootstrap(self):
        Executable('./bootstrap')()

    def configure_args(self):
        spec = self.spec
        config_args = []

        env['CC'] = spec['mpi'].mpicc

        if '+hdf5' in spec:
            config_args.append('--with-hdf5')
            config_args.append('CFLAGS=-D H5_USE_16_API')
        else:
            config_args.append('--without-hdf5')

        if '+ncmpi' in spec:
            config_args.append('--with-ncmpi')
        else:
            config_args.append('--without-ncmpi')

        return config_args
<|endoftext|>


<commit_before>##############################################################################
# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
# LLNL-CODE-647188
#
# For details, see https://github.com/llnl/spack
# Please also see the LICENSE file for our notice and the LGPL.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License (as
# published by the Free Software Foundation) version 2.1, February 1999.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
# conditions of the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
#------------------------------------------------------------------------------
# Author: Justin Too <too1@llnl.gov>
#------------------------------------------------------------------------------
import distutils
from distutils import dir_util
from subprocess import call

import spack
from spack import *
import llnl.util.tty as tty

class Jdk(Package):
    """The Java Development Kit (JDK) released by Oracle Corporation
       in the form of a binary product aimed at Java developers."""
    homepage = "http://www.oracle.com/technetwork/java/javase/downloads/index.html"

    version('8u66-linux-x64', '88f31f3d642c3287134297b8c10e61bf',
        url="http://download.oracle.com/otn-pub/java/jdk/8u66-b17/jdk-8u66-linux-x64.tar.gz")

    # Oracle requires that you accept their License Agreement in order
    # to access the Java packages in download.oracle.com. In order to
    # automate this process, we need to utilize these additional curl
    # commandline options.
    #
    # See http://stackoverflow.com/questions/10268583/how-to-automate-download-and-installation-of-java-jdk-on-linux
    curl_options=[
        '-j', # junk cookies
        '-H', # specify required License Agreement cookie
        'Cookie: oraclelicense=accept-securebackup-cookie']

    def do_fetch(self, mirror_only=False):
        # Add our custom curl commandline options
        tty.msg(
            "[Jdk] Adding required commandline options to curl " +
            "before performing fetch: %s" %
            (self.curl_options))

        for option in self.curl_options:
            spack.curl.add_default_arg(option)

        # Now perform the actual fetch
        super(Jdk, self).do_fetch(mirror_only)

    def install(self, spec, prefix):
        distutils.dir_util.copy_tree(".", prefix)
<commit_msg>Add URL and md5 for jdk-8u92.<commit_after>##############################################################################
# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
# LLNL-CODE-647188
#
# For details, see https://github.com/llnl/spack
# Please also see the LICENSE file for our notice and the LGPL.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License (as
# published by the Free Software Foundation) version 2.1, February 1999.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
# conditions of the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
#------------------------------------------------------------------------------
# Author: Justin Too <too1@llnl.gov>
#------------------------------------------------------------------------------
import distutils
from distutils import dir_util
from subprocess import call

import spack
from spack import *
import llnl.util.tty as tty

class Jdk(Package):
    """The Java Development Kit (JDK) released by Oracle Corporation
       in the form of a binary product aimed at Java developers."""
    homepage = "http://www.oracle.com/technetwork/java/javase/downloads/index.html"

    version('8u66-linux-x64', '88f31f3d642c3287134297b8c10e61bf',
        url="http://download.oracle.com/otn-pub/java/jdk/8u66-b17/jdk-8u66-linux-x64.tar.gz")
    version('8u92-linux-x64', '65a1cc17ea362453a6e0eb4f13be76e4',
        url="http://download.oracle.com/otn-pub/java/jdk/8u92-b14/jdk-8u92-linux-x64.tar.gz")

    # Oracle requires that you accept their License Agreement in order
    # to access the Java packages in download.oracle.com. In order to
    # automate this process, we need to utilize these additional curl
    # commandline options.
    #
    # See http://stackoverflow.com/questions/10268583/how-to-automate-download-and-installation-of-java-jdk-on-linux
    curl_options=[
        '-j', # junk cookies
        '-H', # specify required License Agreement cookie
        'Cookie: oraclelicense=accept-securebackup-cookie']

    def do_fetch(self, mirror_only=False):
        # Add our custom curl commandline options
        tty.msg(
            "[Jdk] Adding required commandline options to curl " +
            "before performing fetch: %s" %
            (self.curl_options))

        for option in self.curl_options:
            spack.curl.add_default_arg(option)

        # Now perform the actual fetch
        super(Jdk, self).do_fetch(mirror_only)

    def install(self, spec, prefix):
        distutils.dir_util.copy_tree(".", prefix)
<|endoftext|>


<commit_before># Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *

class Vim(AutotoolsPackage):
    """Vim is a highly configurable text editor built to enable efficient text
    editing. It is an improved version of the vi editor distributed with most
    UNIX systems.  Vim is often called a "programmer's editor," and so useful
    for programming that many consider it an entire IDE. It's not just for
    programmers, though. Vim is perfect for all kinds of text editing, from
    composing email to editing configuration files.
    """

    homepage = "http://www.vim.org"
    url      = "https://github.com/vim/vim/archive/v8.1.0338.tar.gz"

    version('8.2.1201', sha256='39032fe866f44724b104468038dc9ac4ff2c00a4b18c9a1e2c27064ab1f1143d')
    version('8.1.2141', sha256='7be3c3d88a6c871121230ffb9b7371b1d2ab462118dedb967c7265473af1144b')
    version('8.1.0338', sha256='3febcc4e49eaca458be1a1e8055a3a52887aa2054b03e24d5f38d192c3de51a0')
    version('8.1.0001', sha256='c342acaa26589f371fa34a5ca213b95811f26185c12443f8f48ad2868dee2935')
    version('8.0.1376', sha256='1ad8b5a0b9b63df5abc3f8050e31e1cb49379ffcfd2662a56daeff8bd3d780b9')
    version('8.0.0503', sha256='f2a316a7ae83eccfecf4a700e631094fce9df873358e3d5f112134faa74082ac')
    version('8.0.0454', sha256='e1f683c4a0e3fa56fa02769bbca576e4960850b0ca8640514a7b114b88c27b89')
    version('8.0.0134', sha256='1b3e3e7d187eed55cbdb0a1dae6b8f3b885005fbae84222420877d7afa3b2310')
    version('7.4.2367', sha256='a9ae4031ccd73cc60e771e8bf9b3c8b7f10f63a67efce7f61cd694cd8d7cda5c')

    feature_sets = ('huge', 'big', 'normal', 'small', 'tiny')
    for fs in feature_sets:
        variant(fs, default=False, description="Use '%s' feature set" % fs)

    variant('python', default=False, description="build with Python")
    depends_on('python', when='+python')

    variant('ruby', default=False, description="build with Ruby")
    depends_on('ruby', when='+ruby')

    variant('lua', default=False, description="build with Lua")
    depends_on('lua', when='+lua')

    variant('perl', default=False, description="build with Perl")
    depends_on('perl', when='+perl')

    variant('cscope', default=False, description="build with cscope support")
    depends_on('cscope', when='+cscope', type='run')

    # TODO: Once better support for multi-valued variants is added, add
    # support for auto/no/gtk2/gnome2/gtk3/motif/athena/neXtaw/photon/carbon
    variant('gui', default=False, description="build with gui (gvim)")
    variant('x', default=False, description="use the X Window System")
    depends_on('libx11', when="+x")
    depends_on('libsm', when="+x")
    depends_on('libxpm', when="+x")
    depends_on('libxt', when="+x")
    depends_on('libxtst', when="+x")

    depends_on('ncurses', when="@7.4:")
    depends_on('findutils', type='build')
    depends_on('fontconfig', when="+gui")

    def configure_args(self):
        spec = self.spec
        feature_set = None
        for fs in self.feature_sets:
            if "+" + fs in spec:
                if feature_set is not None:
                    raise InstallError(
                        "Only one feature set allowed, specified %s and %s"
                        % (feature_set, fs))
                feature_set = fs
        if '+gui' in spec:
            if feature_set is not None:
                if feature_set != 'huge':
                    raise InstallError(
                        "+gui variant requires 'huge' feature set, "
                        "%s was specified" % feature_set)
            feature_set = 'huge'
        if feature_set is None:
            feature_set = 'normal'

        configure_args = ["--enable-fail-if-missing"]

        if '+termlib' in spec['ncurses']:
            configure_args.append("--with-tlib=tinfow")
        else:
            configure_args.append("--with-tlib=ncursesw")

        configure_args.append("--with-features=" + feature_set)

        if '+python' in spec:
            if 'python@3:' in self.spec:
                configure_args.append("--enable-python3interp=dynamic")
                configure_args.append("--enable-pythoninterp=no")
            else:
                configure_args.append("--enable-python3interp=no")
                configure_args.append("--enable-pythoninterp=dynamic")
        else:
            configure_args.append("--enable-python3interp=no")

        if '+ruby' in spec:
            configure_args.append("--enable-rubyinterp=yes")
        else:
            configure_args.append("--enable-rubyinterp=no")

        if '+lua' in spec:
            configure_args.append("--enable-luainterp=yes")
            configure_args.append("--with-lua-prefix=%s" % spec['lua'].prefix)
        else:
            configure_args.append("--enable-luainterp=no")

        if '+perl' in spec:
            configure_args.append("--enable-perlinterp=yes")
        else:
            configure_args.append("--enable-perlinterp=no")

        if '+gui' in spec:
            configure_args.append("--enable-gui=auto")
        else:
            configure_args.append("--enable-gui=no")

        if '+x' in spec:
            configure_args.append("--with-x")
        else:
            configure_args.append("--without-x")

        if '+cscope' in spec:
            configure_args.append("--enable-cscope")

        return configure_args

    # Tests must be run in serial
    def check(self):
        make('test', parallel=False)

    # Run the install phase with -j 1.  There seems to be a problem with
    # parallel builds that results in the creation of the links (e.g. view)
    # to the vim binary silently failing.
    def install(self, spec, prefix):
        make('install', parallel=False)
<commit_msg>vim: add new version (#23730)<commit_after># Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *

class Vim(AutotoolsPackage):
    """Vim is a highly configurable text editor built to enable efficient text
    editing. It is an improved version of the vi editor distributed with most
    UNIX systems.  Vim is often called a "programmer's editor," and so useful
    for programming that many consider it an entire IDE. It's not just for
    programmers, though. Vim is perfect for all kinds of text editing, from
    composing email to editing configuration files.
    """

    homepage = "http://www.vim.org"
    url      = "https://github.com/vim/vim/archive/v8.1.0338.tar.gz"

    version('8.2.2541', sha256='2699dfe87b524169e7390f0b383c406cb77a9fde7431665d3b9b80964d8d5daf')
    version('8.2.1201', sha256='39032fe866f44724b104468038dc9ac4ff2c00a4b18c9a1e2c27064ab1f1143d')
    version('8.2.0752', sha256='d616945810dac5a1fab2f23b003d22bdecd34861b31f208d5d0012a609821c0f')
    version('8.1.2141', sha256='7be3c3d88a6c871121230ffb9b7371b1d2ab462118dedb967c7265473af1144b')
    version('8.1.0338', sha256='3febcc4e49eaca458be1a1e8055a3a52887aa2054b03e24d5f38d192c3de51a0')
    version('8.1.0001', sha256='c342acaa26589f371fa34a5ca213b95811f26185c12443f8f48ad2868dee2935')
    version('8.0.1376', sha256='1ad8b5a0b9b63df5abc3f8050e31e1cb49379ffcfd2662a56daeff8bd3d780b9')
    version('8.0.0503', sha256='f2a316a7ae83eccfecf4a700e631094fce9df873358e3d5f112134faa74082ac')
    version('8.0.0454', sha256='e1f683c4a0e3fa56fa02769bbca576e4960850b0ca8640514a7b114b88c27b89')
    version('8.0.0134', sha256='1b3e3e7d187eed55cbdb0a1dae6b8f3b885005fbae84222420877d7afa3b2310')
    version('7.4.2367', sha256='a9ae4031ccd73cc60e771e8bf9b3c8b7f10f63a67efce7f61cd694cd8d7cda5c')

    feature_sets = ('huge', 'big', 'normal', 'small', 'tiny')
    for fs in feature_sets:
        variant(fs, default=False, description="Use '%s' feature set" % fs)

    variant('python', default=False, description="build with Python")
    depends_on('python', when='+python')

    variant('ruby', default=False, description="build with Ruby")
    depends_on('ruby', when='+ruby')

    variant('lua', default=False, description="build with Lua")
    depends_on('lua', when='+lua')

    variant('perl', default=False, description="build with Perl")
    depends_on('perl', when='+perl')

    variant('cscope', default=False, description="build with cscope support")
    depends_on('cscope', when='+cscope', type='run')

    # TODO: Once better support for multi-valued variants is added, add
    # support for auto/no/gtk2/gnome2/gtk3/motif/athena/neXtaw/photon/carbon
    variant('gui', default=False, description="build with gui (gvim)")
    variant('x', default=False, description="use the X Window System")
    depends_on('libx11', when="+x")
    depends_on('libsm', when="+x")
    depends_on('libxpm', when="+x")
    depends_on('libxt', when="+x")
    depends_on('libxtst', when="+x")

    depends_on('ncurses', when="@7.4:")
    depends_on('findutils', type='build')
    depends_on('fontconfig', when="+gui")

    def configure_args(self):
        spec = self.spec
        feature_set = None
        for fs in self.feature_sets:
            if "+" + fs in spec:
                if feature_set is not None:
                    raise InstallError(
                        "Only one feature set allowed, specified %s and %s"
                        % (feature_set, fs))
                feature_set = fs
        if '+gui' in spec:
            if feature_set is not None:
                if feature_set != 'huge':
                    raise InstallError(
                        "+gui variant requires 'huge' feature set, "
                        "%s was specified" % feature_set)
            feature_set = 'huge'
        if feature_set is None:
            feature_set = 'normal'

        configure_args = ["--enable-fail-if-missing"]

        if '+termlib' in spec['ncurses']:
            configure_args.append("--with-tlib=tinfow")
        else:
            configure_args.append("--with-tlib=ncursesw")

        configure_args.append("--with-features=" + feature_set)

        if '+python' in spec:
            if 'python@3:' in self.spec:
                configure_args.append("--enable-python3interp=dynamic")
                configure_args.append("--enable-pythoninterp=no")
            else:
                configure_args.append("--enable-python3interp=no")
                configure_args.append("--enable-pythoninterp=dynamic")
        else:
            configure_args.append("--enable-python3interp=no")

        if '+ruby' in spec:
            configure_args.append("--enable-rubyinterp=yes")
        else:
            configure_args.append("--enable-rubyinterp=no")

        if '+lua' in spec:
            configure_args.append("--enable-luainterp=yes")
            configure_args.append("--with-lua-prefix=%s" % spec['lua'].prefix)
        else:
            configure_args.append("--enable-luainterp=no")

        if '+perl' in spec:
            configure_args.append("--enable-perlinterp=yes")
        else:
            configure_args.append("--enable-perlinterp=no")

        if '+gui' in spec:
            configure_args.append("--enable-gui=auto")
        else:
            configure_args.append("--enable-gui=no")

        if '+x' in spec:
            configure_args.append("--with-x")
        else:
            configure_args.append("--without-x")

        if '+cscope' in spec:
            configure_args.append("--enable-cscope")

        return configure_args

    # Tests must be run in serial
    def check(self):
        make('test', parallel=False)

    # Run the install phase with -j 1.  There seems to be a problem with
    # parallel builds that results in the creation of the links (e.g. view)
    # to the vim binary silently failing.
    def install(self, spec, prefix):
        make('install', parallel=False)
<|endoftext|>


<commit_before># Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *

class Zfp(CMakePackage, CudaPackage):
    """zfp is a compressed number format for multidimensional floating-point
       and integer arrays.

       zfp provides compressed-array classes that support high throughput
       read and write random access to individual array elements. zfp also
       supports serial and parallel (OpenMP and CUDA) compression of whole
       arrays.
    """

    # Package info
    homepage    = 'https://zfp.llnl.gov'
    url         = 'https://github.com/LLNL/zfp/releases/download/0.5.5/zfp-0.5.5.tar.gz'
    git         = 'https://github.com/LLNL/zfp.git'
    maintainers = ['lindstro', 'GarrettDMorrison']

    # Versions
    version('develop', branch='develop')
    version('0.5.5', sha256='fdf7b948bab1f4e5dccfe2c2048fd98c24e417ad8fb8a51ed3463d04147393c5')
    version('0.5.4', sha256='746e17aaa401c67dcffd273d6e6f95c76adfbbd5cf523dcad56d09e9d3b71196')
    version('0.5.3', sha256='a5d2f8e5b47a7c92e2a5775b82cbfb3a76c87d0ac83d25abb4ac10ea75a2856e')
    version('0.5.2', sha256='9c738ec525cc76b4bb80b2b3f7c9f07507eeda3a341470e5942cda97efbe9a4f', url='https://github.com/LLNL/zfp/archive/0.5.2/zfp-0.5.2.tar.gz')
    version('0.5.1', sha256='f255dd1708c9ae4dc6a56dd2614e8b47a10d833c87fd349cbd47545a19c2b779', url='https://github.com/LLNL/zfp/archive/0.5.1/zfp-0.5.1.tar.gz')

    # Build targets
    # TODO: variant('utilities', default=True,  description='Build utilities')
    variant('shared',    default=True,  description='Build shared libraries')

    # Language bindings
    variant('c',       default=False, description='Enable C bindings')
    variant('python',  default=False, description='Enable Python bindings')
    variant('fortran', default=False, description='Enable Fortran bindings')

    # Execution policies
    variant('openmp', default=False, description='Enable OpenMP execution')
    variant('cuda',   default=False, description='Enable CUDA execution')

    # Advanced options
    variant('bsws', default='64', values=('8', '16', '32', '64'), multi=False,
            description='Bit stream word size: '
            'use smaller for finer rate granularity. '
            'Use 8 for H5Z-ZFP filter.')
    variant('strided', default=False,
            description='Enable strided access for progressive zfp streams')
    variant('aligned', default=False,
            description='Enable aligned memory allocation')
    variant('twoway', default=False,
            description='Use two-way skew-associative cache')
    variant('fasthash', default=False,
            description='Use a faster but more collision prone hash function')
    variant('profile', default=False,
            description='Count cache misses')

    # Conflicts
    conflicts('+c',        when='@:0.5.3',
              msg='+c requires zfp 0.5.4 or later')
    conflicts('+python',   when='@:0.5.4',
              msg='+python requires zfp 0.5.5 or later')
    conflicts('+fortran',  when='@:0.5.4',
              msg='+fortran requires zfp 0.5.5 or later')
    conflicts('+openmp',   when='@:0.5.2',
              msg='+openmp requires zfp 0.5.3 or later')
    conflicts('+cuda',     when='@:0.5.3',
              msg='+cuda requires zfp 0.5.4 or later')
    conflicts('+fasthash', when='@:0.5.1',
              msg='+fasthash requires zfp 0.5.2 or later')
    conflicts('+profile',  when='@:0.5.1',
              msg='+profile requires zfp 0.5.2 or later')

    # Dependencies
    depends_on('cmake@3.4.0:', type='build')
    depends_on('cuda@7:',      type=('build', 'test', 'run'), when='+cuda')
    depends_on('python',     type=('build', 'test', 'run'), when='+python')
    depends_on('py-numpy',     type=('build', 'test', 'run'), when='+python')
    depends_on('py-cython',    type='build',                  when='+python')

    def cmake_args(self):
        spec = self.spec

        # CMake options
        args = [
            # TODO: self.define_from_variant('BUILD_UTILITIES', 'utilities'),
            self.define('BUILD_TESTING', self.run_tests),
            self.define_from_variant('BUILD_SHARED_LIBS', 'shared'),
            self.define_from_variant('BUILD_CFP', 'c'),
            self.define_from_variant('BUILD_ZFPY', 'python'),
            self.define_from_variant('BUILD_ZFORP', 'fortran'),
            self.define('ZFP_BIT_STREAM_WORD_SIZE',
                        spec.variants['bsws'].value),
            self.define_from_variant('ZFP_WITH_BIT_STREAM_STRIDED', 'strided'),
            self.define_from_variant('ZFP_WITH_ALIGNED_ALLOC', 'aligned'),
            self.define_from_variant('ZFP_WITH_CACHE_TWOWAY', 'twoway'),
            self.define_from_variant('ZFP_WITH_CACHE_FAST_HASH', 'fasthash'),
            self.define_from_variant('ZFP_WITH_CACHE_PROFILE', 'profile')
        ]

        return args
<commit_msg>Fix ZFP cuda build. (#23941)<commit_after># Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *

class Zfp(CMakePackage, CudaPackage):
    """zfp is a compressed number format for multidimensional floating-point
       and integer arrays.

       zfp provides compressed-array classes that support high throughput
       read and write random access to individual array elements. zfp also
       supports serial and parallel (OpenMP and CUDA) compression of whole
       arrays.
    """

    # Package info
    homepage    = 'https://zfp.llnl.gov'
    url         = 'https://github.com/LLNL/zfp/releases/download/0.5.5/zfp-0.5.5.tar.gz'
    git         = 'https://github.com/LLNL/zfp.git'
    maintainers = ['lindstro', 'GarrettDMorrison']

    # Versions
    version('develop', branch='develop')
    version('0.5.5', sha256='fdf7b948bab1f4e5dccfe2c2048fd98c24e417ad8fb8a51ed3463d04147393c5')
    version('0.5.4', sha256='746e17aaa401c67dcffd273d6e6f95c76adfbbd5cf523dcad56d09e9d3b71196')
    version('0.5.3', sha256='a5d2f8e5b47a7c92e2a5775b82cbfb3a76c87d0ac83d25abb4ac10ea75a2856e')
    version('0.5.2', sha256='9c738ec525cc76b4bb80b2b3f7c9f07507eeda3a341470e5942cda97efbe9a4f', url='https://github.com/LLNL/zfp/archive/0.5.2/zfp-0.5.2.tar.gz')
    version('0.5.1', sha256='f255dd1708c9ae4dc6a56dd2614e8b47a10d833c87fd349cbd47545a19c2b779', url='https://github.com/LLNL/zfp/archive/0.5.1/zfp-0.5.1.tar.gz')

    # Build targets
    # TODO: variant('utilities', default=True,  description='Build utilities')
    variant('shared',    default=True,  description='Build shared libraries')

    # Language bindings
    variant('c',       default=False, description='Enable C bindings')
    variant('python',  default=False, description='Enable Python bindings')
    variant('fortran', default=False, description='Enable Fortran bindings')

    # Execution policies
    variant('openmp', default=False, description='Enable OpenMP execution')
    variant('cuda',   default=False, description='Enable CUDA execution')

    # Advanced options
    variant('bsws', default='64', values=('8', '16', '32', '64'), multi=False,
            description='Bit stream word size: '
            'use smaller for finer rate granularity. '
            'Use 8 for H5Z-ZFP filter.')
    variant('strided', default=False,
            description='Enable strided access for progressive zfp streams')
    variant('aligned', default=False,
            description='Enable aligned memory allocation')
    variant('twoway', default=False,
            description='Use two-way skew-associative cache')
    variant('fasthash', default=False,
            description='Use a faster but more collision prone hash function')
    variant('profile', default=False,
            description='Count cache misses')

    # Conflicts
    conflicts('+c',        when='@:0.5.3',
              msg='+c requires zfp 0.5.4 or later')
    conflicts('+python',   when='@:0.5.4',
              msg='+python requires zfp 0.5.5 or later')
    conflicts('+fortran',  when='@:0.5.4',
              msg='+fortran requires zfp 0.5.5 or later')
    conflicts('+openmp',   when='@:0.5.2',
              msg='+openmp requires zfp 0.5.3 or later')
    conflicts('+cuda',     when='@:0.5.3',
              msg='+cuda requires zfp 0.5.4 or later')
    conflicts('+fasthash', when='@:0.5.1',
              msg='+fasthash requires zfp 0.5.2 or later')
    conflicts('+profile',  when='@:0.5.1',
              msg='+profile requires zfp 0.5.2 or later')

    # Dependencies
    depends_on('cmake@3.4.0:', type='build')
    depends_on('cuda@7:',      type=('build', 'test', 'run'), when='+cuda')
    depends_on('python',     type=('build', 'test', 'run'), when='+python')
    depends_on('py-numpy',     type=('build', 'test', 'run'), when='+python')
    depends_on('py-cython',    type='build',                  when='+python')

    def cmake_args(self):
        spec = self.spec

        # CMake options
        args = [
            # TODO: self.define_from_variant('BUILD_UTILITIES', 'utilities'),
            self.define('BUILD_TESTING', self.run_tests),
            self.define_from_variant('BUILD_SHARED_LIBS', 'shared'),
            self.define_from_variant('BUILD_CFP', 'c'),
            self.define_from_variant('BUILD_ZFPY', 'python'),
            self.define_from_variant('BUILD_ZFORP', 'fortran'),
            self.define_from_variant('ZFP_WITH_CUDA', 'cuda'),
            self.define('ZFP_BIT_STREAM_WORD_SIZE',
                        spec.variants['bsws'].value),
            self.define_from_variant('ZFP_WITH_BIT_STREAM_STRIDED', 'strided'),
            self.define_from_variant('ZFP_WITH_ALIGNED_ALLOC', 'aligned'),
            self.define_from_variant('ZFP_WITH_CACHE_TWOWAY', 'twoway'),
            self.define_from_variant('ZFP_WITH_CACHE_FAST_HASH', 'fasthash'),
            self.define_from_variant('ZFP_WITH_CACHE_PROFILE', 'profile'),
        ]

        if '+cuda' in spec:
            args.append('-DCUDA_BIN_DIR={0}'.format(spec['cuda'].prefix.bin))

            if not spec.satisfies('cuda_arch=none'):
                cuda_arch = spec.variants['cuda_arch'].value
                args.append('-DCMAKE_CUDA_FLAGS=-arch sm_{0}'.format(cuda_arch[0]))

        return args
<|endoftext|>