Beispiel #1
0
def emissions_comparison(process_kwh, locations, year):
    # TODO: Disambiguation of states such as Georgia, US and Georgia
    intl_data = utils.get_data("data/json/energy-mix-intl_" + year + ".json")
    us_data = utils.get_data("data/json/us-emissions_" + year + ".json")
    emissions = []  # list of tuples w/ format (location, emission)

    for location in locations:
        if locate.in_US(location):
            emission = convert.lbs_to_kgs(us_data[location] *
                                          convert.to_MWh(process_kwh))
            emissions.append((location, emission))
        else:
            c = intl_data[location]
            total, breakdown = c['total'], [c['coal'], c['petroleum'], \
            c['naturalGas'], c['lowCarbon']]
            if isinstance(total, float) and float(total) > 0:
                breakdown = list(map(lambda x: 100 * x / total, breakdown))
                coal, petroleum, natural_gas, low_carbon = breakdown
                breakdown = [
                    convert.coal_to_carbon(process_kwh * coal / 100),
                    convert.petroleum_to_carbon(process_kwh * petroleum / 100),
                    convert.natural_gas_to_carbon(process_kwh * natural_gas /
                                                  100), 0
                ]
                emission = sum(breakdown)
                emissions.append((location, emission))

    if emissions != []:
        utils.log('Emissions Comparison', emissions)
    return emissions
Beispiel #2
0
def old_emissions_comparison(process_kwh, year, default_location,
                             printToScreen):
    # Calculates emissions in different locations

    intl_data = utils.get_data("data/json/energy-mix-intl_" + year + ".json")
    global_emissions, europe_emissions, us_emissions = [], [], []
    # Handling international
    for country in intl_data:
        c = intl_data[country]
        total, breakdown = c['total'], [c['coal'], c['petroleum'], \
        c['naturalGas'], c['lowCarbon']]
        if isinstance(total, float) and float(total) > 0:
            breakdown = list(map(lambda x: 100 * x / total, breakdown))
            coal, petroleum, natural_gas, low_carbon = breakdown
            breakdown = [
                convert.coal_to_carbon(process_kwh * coal / 100),
                convert.petroleum_to_carbon(process_kwh * petroleum / 100),
                convert.natural_gas_to_carbon(process_kwh * natural_gas / 100),
                0
            ]
            emission = sum(breakdown)
            if locate.in_Europe(country):
                europe_emissions.append((country, emission))
            else:
                global_emissions.append((country, emission))

    global_emissions.sort(key=lambda x: x[1])
    europe_emissions.sort(key=lambda x: x[1])

    # Handling US
    us_data = utils.get_data("data/json/us-emissions_" + year + ".json")
    for state in us_data:
        if ((state != "United States") and state != "_units"):
            if us_data[state] != "lbs/MWh":
                emission = convert.lbs_to_kgs(us_data[state] *
                                              convert.to_MWh(process_kwh))
                us_emissions.append((state, emission))
    us_emissions.sort(key=lambda x: x[1])

    max_global, max_europe, max_us = global_emissions[len(global_emissions)-1], \
        europe_emissions[len(europe_emissions)-1], us_emissions[len(us_emissions)-1]
    median_global, median_europe, median_us = global_emissions[len(global_emissions)//2], \
        europe_emissions[len(europe_emissions)//2], us_emissions[len(us_emissions)//2]
    min_global, min_europe, min_us = global_emissions[0], europe_emissions[
        0], us_emissions[0]
    if default_location and printToScreen:
        utils.log('Emissions Comparison default', max_global, median_global, min_global, max_europe, \
            median_europe, min_europe, max_us, median_us, min_us)
    default_emissions = [max_global, median_global, min_global, max_europe, \
        median_europe, min_europe, max_us, median_us, min_us]
    return default_emissions
Beispiel #3
0
def emissions(process_kwh, breakdown, location, year):
    """ Calculates the CO2 emitted by the program based on the location

        Parameters:
            process_kwh (int): kWhs used by the process
            breakdown (list): energy mix corresponding to user's location
            location (str): location of user

        Returns:
            emission (float): kilograms of CO2 emitted
            state_emission (float): lbs CO2 per MWh; 0 if international location

    """

    if process_kwh < 0:
        raise OSError(
            "Process wattage lower than baseline wattage. Do not run other processes"
            " during the evaluation, or try evaluating a more resource-intensive process."
        )

    utils.log("Energy Data", breakdown, location)
    state_emission = 0

    # Case 1: Unknown location, default to US data
    # Case 2: United States location
    if locate.in_US(location):
        if location == "Unknown":
            location = "United States"
        # US Emissions data is in lbs/Mwh
        data = utils.get_data("data/json/us-emissions_" + year + ".json")
        state_emission = data[location]
        emission = convert.lbs_to_kgs(state_emission *
                                      convert.to_MWh(process_kwh))

    # Case 3: International location
    else:
        # Breaking down energy mix
        coal, petroleum, natural_gas, low_carbon = breakdown
        breakdown = [
            convert.coal_to_carbon(process_kwh * coal / 100),
            convert.petroleum_to_carbon(process_kwh * petroleum / 100),
            convert.natural_gas_to_carbon(process_kwh * natural_gas / 100), 0
        ]
        emission = sum(breakdown)

    utils.log("Emissions", emission)
    return (emission, state_emission)
def evaluate(user_func, *args, pdf=False, powerLoss=0.8, energyOutput=False, \
            location_of_default = "GlobalAverage", printToScreen = True):
    """ Calculates effective emissions of the function

        Parameters:
            user_func: user inputtted function
            pdf (bool): whether a PDF report should be generated
            powerLoss (float): PSU efficiency rating

    """
    utils.setGlobal(printToScreen)

    if (utils.valid_cpu() or utils.valid_gpu()):
        location = locate.get(printToScreen)
        result, return_value, watt_averages, files, total_time = energy(user_func, *args, powerLoss=powerLoss, \
                                                                        printToScreen = printToScreen)
        breakdown = energy_mix(location, location_of_default)
        emission, state_emission = emissions(result, breakdown, location,
                                             location_of_default)
        utils.log("Assumed Carbon Equivalencies")
        emissions_comparison(result)
        utils.log("Process Energy", result)
        if pdf:
            report.generate(location, watt_averages, breakdown, emission,
                            state_emission)
        if energyOutput:
            return (total_time, result, return_value)
        else:
            return return_value

    else:
        utils.log(
            "The energy-usage package only works on Linux kernels "
            "with Intel processors that support the RAPL interface and/or machines with"
            " an Nvidia GPU. Please try again on a different machine.")
Beispiel #5
0
def evaluate(user_func, *args, pdf=False, powerLoss=0.8, energyOutput=False, \
locations=["Mongolia", "Iceland", "Switzerland"], year="2016", printToScreen = True):
    """ Calculates effective emissions of the function

        Parameters:
            user_func: user's function + associated args
            pdf (bool): whether a PDF report should be generated
            powerLoss (float): PSU efficiency rating
            energyOutput (bool): return value also includes information about energy usage, not just function's return
            locations (list of strings): list of locations to be compared
            year (str): year of dataset to be used
            printToScreen (bool): get information in the command line

    """
    utils.setGlobal(printToScreen)
    if (utils.valid_cpu() or utils.valid_gpu()):
        location = locate.get(printToScreen)
        result, return_value, watt_averages, files, total_time = energy(user_func, *args, powerLoss = powerLoss, year = year, \
                                                            printToScreen = printToScreen)
        default_location = False
        if locations == ["Mongolia", "Iceland", "Switzerland"]:
            default_location = True
        breakdown = energy_mix(location, year=year)
        emission, state_emission = emissions(result, breakdown, location, year,
                                             printToScreen)
        if printToScreen:
            utils.log("Assumed Carbon Equivalencies")
        comparison_values = emissions_comparison(result, locations, year,
                                                 default_location,
                                                 printToScreen)
        default_emissions = old_emissions_comparison(result, year,
                                                     default_location,
                                                     printToScreen)
        if printToScreen:
            utils.log("Process Energy", result)
        func_info = [user_func.__name__, *args]
        kwh_and_emissions = [result, emission, state_emission]
        if pdf:
            #pass
            report.generate(location, watt_averages, breakdown, kwh_and_emissions, \
                func_info, comparison_values, default_emissions, default_location)
        if energyOutput:
            return (total_time, result, return_value)
        else:
            return return_value

    else:
        utils.log(
            "The energy-usage package only works on Linux kernels "
            "with Intel processors that support the RAPL interface and/or machines with"
            " an Nvidia GPU. Please try again on a different machine.")
Beispiel #6
0
def energy(user_func, *args, powerLoss=0.8, year, printToScreen):
    """ Evaluates the kwh needed for your code to run

    Parameters:
       user_func (function): user's function

    Returns:
        (process_kwh, return_value, watt_averages)

    """

    baseline_check_seconds = 2
    files, multiple_cpus = utils.get_files()
    is_nvidia_gpu = utils.valid_gpu()
    is_valid_cpu = utils.valid_cpu()

    # GPU handling if Nvidia
    gpu_baseline = [0]
    gpu_process = [0]
    bash_command = "nvidia-smi -i 0 --format=csv,noheader --query-gpu=power.draw"

    for i in range(int(baseline_check_seconds / DELAY)):
        if is_nvidia_gpu:
            output = subprocess.check_output(['bash', '-c', bash_command])
            output = float(output.decode("utf-8")[:-2])
            gpu_baseline.append(output)
        if is_valid_cpu:
            files = utils.measure_files(files, DELAY)
            files = utils.update_files(files)
        else:
            time.sleep(DELAY)
        # Adds the most recent value of GPU; 0 if not Nvidia
        last_reading = utils.get_total(files, multiple_cpus) + gpu_baseline[-1]
        if last_reading >= 0:
            utils.log("Baseline wattage", last_reading)
    if printToScreen:
        utils.newline()

    # Running the process and measuring wattage
    q = Queue()
    p = Process(target=func, args=(
        user_func,
        q,
        *args,
    ))

    start = timer()
    p.start()
    small_delay_counter = 0
    return_value = None
    while (p.is_alive()):
        # Checking at a faster rate for quick processes
        if (small_delay_counter > DELAY):
            delay = DELAY / 10
            small_delay_counter += 1
        else:
            delay = DELAY

        if is_nvidia_gpu:
            output = subprocess.check_output(['bash', '-c', bash_command])
            output = float(output.decode("utf-8")[:-2])
            gpu_process.append(output)
        if is_valid_cpu:
            files = utils.measure_files(files, delay)
            files = utils.update_files(files, True)
        else:
            time.sleep(delay)
        # Just output, not added
        last_reading = (utils.get_total(files, multiple_cpus) +
                        gpu_process[-1]) / powerLoss
        if last_reading >= 0:
            utils.log("Process wattage", last_reading)
    # Getting the return value of the user's function
        try:
            return_value = q.get_nowait()
            break
        except queue.Empty:
            pass
    p.join()
    end = timer()
    for file in files:
        file.process = file.process[1:-1]
        file.baseline = file.baseline[1:-1]
    if is_nvidia_gpu:
        gpu_baseline_average = statistics.mean(gpu_baseline[2:-1])
        gpu_process_average = statistics.mean(gpu_process[2:-1])
    else:
        gpu_baseline_average = 0
        gpu_process_average = 0

    total_time = end - start  # seconds
    # Formatting the time nicely
    timedelta = str(datetime.timedelta(seconds=total_time)).split('.')[0]

    files = utils.average_files(files)

    process_average = utils.get_process_average(files, multiple_cpus,
                                                gpu_process_average)
    baseline_average = utils.get_baseline_average(files, multiple_cpus,
                                                  gpu_baseline_average)
    difference_average = process_average - baseline_average
    watt_averages = [
        baseline_average, process_average, difference_average, timedelta
    ]

    # Subtracting baseline wattage to get more accurate result
    process_kwh = convert.to_kwh(
        (process_average - baseline_average) * total_time) / powerLoss

    if is_nvidia_gpu:
        gpu_file = file("GPU", "")
        gpu_file.create_gpu(gpu_baseline_average, gpu_process_average)
        files.append(file("GPU", ""))

    # Logging
    utils.log("Final Readings", baseline_average, process_average,
              difference_average, timedelta)
    return (process_kwh, return_value, watt_averages, files, total_time)