Adjust memory based on number of cores utilized.

def adjust_memory(val, magnitude, direction="increase", out_modifier="", maximum=None):
    """Adjust memory based on number of cores utilized.
    """
    modifier = val[-1:]
    amount = float(val[:-1])
    if direction == "decrease":
        new_amount = amount / float(magnitude)
        # dealing with a specifier like 1G, need to scale to Mb
        if new_amount < 1 or (out_modifier.upper().startswith("M") and modifier.upper().startswith("G")):
            if modifier.upper().startswith("G"):
                new_amount = (amount * 1024) / magnitude
                modifier = "M" + modifier[1:]
            else:
                raise ValueError("Unexpected decrease in memory: %s by %s" % (val, magnitude))
        amount = int(new_amount)
    elif direction == "increase" and magnitude > 1:
        # for increases with multiple cores, leave small percentage of
        # memory for system to maintain process running resource and
        # avoid OOM killers
        adjuster = 0.91
        amount = int(math.ceil(amount * (adjuster * magnitude)))
    if out_modifier.upper().startswith("G") and modifier.upper().startswith("M"):
        modifier = out_modifier
        amount = int(math.floor(amount / 1024.0))
    if out_modifier.upper().startswith("M") and modifier.upper().startswith("G"):
        modifier = out_modifier
        modifier = int(amount * 1024)
    if maximum:
        max_modifier = maximum[-1]
        max_amount = float(maximum[:-1])
        if modifier.upper() == "G" and max_modifier.upper() == "M":
            max_amount = max_amount / 1024.0
        elif modifier.upper() == "M" and max_modifier.upper() == "G":
            max_amount = max_amount * 1024.0
        amount = min([amount, max_amount])
    return "{amount}{modifier}".format(amount=int(math.floor(amount)), modifier=modifier)