From 0da16ae8a69c74ed39f5039f0de8524fd466538a Mon Sep 17 00:00:00 2001 From: kadan Date: Mon, 22 Jul 2019 16:35:18 -0400 Subject: [PATCH] Final changes needed before making pip installable --- AUTHORS.txt | 3 +- LICENSE | 21 --------- LICENSE.txt | 13 ++++++ MANIFEST.in | 12 ++++++ __init__.py | 1 - data/__init__.py | 0 {energy-meter => energy_usage}/RAPLFile.py | 0 energy_usage/__init__.py | 1 + {energy-meter => energy_usage}/convert.py | 0 {data => energy_usage/data}/README.md | 0 .../data}/csv/emissions-us.csv | 0 .../data}/csv/energy-mix-intl.csv | 0 .../data}/csv/energy-mix-us.csv | 0 .../data}/json/energy-mix-intl.json | 0 .../data}/json/energy-mix-us.json | 0 .../data}/json/us-emissions.json | 0 .../energy-meter.py | 2 + {energy-meter => energy_usage}/evaluate.py | 34 ++++----------- {energy-meter => energy_usage}/locate.py | 1 - {energy-meter => energy_usage}/utils.py | 43 +++++-------------- requirements.txt | 2 +- setup.py | 23 +++++----- 22 files changed, 61 insertions(+), 95 deletions(-) delete mode 100644 LICENSE create mode 100644 LICENSE.txt create mode 100644 MANIFEST.in delete mode 100644 __init__.py delete mode 100644 data/__init__.py rename {energy-meter => energy_usage}/RAPLFile.py (100%) create mode 100644 energy_usage/__init__.py rename {energy-meter => energy_usage}/convert.py (100%) rename {data => energy_usage/data}/README.md (100%) rename {data => energy_usage/data}/csv/emissions-us.csv (100%) rename {data => energy_usage/data}/csv/energy-mix-intl.csv (100%) rename {data => energy_usage/data}/csv/energy-mix-us.csv (100%) rename {data => energy_usage/data}/json/energy-mix-intl.json (100%) rename {data => energy_usage/data}/json/energy-mix-us.json (100%) rename {data => energy_usage/data}/json/us-emissions.json (100%) rename {energy-meter => energy_usage}/energy-meter.py (92%) rename {energy-meter => energy_usage}/evaluate.py (88%) rename {energy-meter => energy_usage}/locate.py (99%) rename {energy-meter => energy_usage}/utils.py (91%) diff --git a/AUTHORS.txt b/AUTHORS.txt index 2983e91..6175a78 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -1,2 +1,3 @@ +* Sorelle Friedler +* Kadan Lottick * Silvia Susai -* Kadan Lottick \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index b2dec3e..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 by author list (see AUTHORS.txt) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..75a1d19 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,13 @@ + Copyright 2019 by authors list (see AUTHORS.txt) + + 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. diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..9482e7b --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,12 @@ +recursive-include energy_usage *.py *.md *.txt + +include requirements*.* +include README.* + +graft energy_usage/data/json +graft energy_usage/data/csv + +recursive-exclude ./dist *.py *.R *.Rmd *.md *.txt +recursive-exclude ./build *.py *.R *.Rmd *.md *.txt + +prune venv diff --git a/__init__.py b/__init__.py deleted file mode 100644 index 51263dd..0000000 --- a/__init__.py +++ /dev/null @@ -1 +0,0 @@ -name = "energy-usage" diff --git a/data/__init__.py b/data/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/energy-meter/RAPLFile.py b/energy_usage/RAPLFile.py similarity index 100% rename from energy-meter/RAPLFile.py rename to energy_usage/RAPLFile.py diff --git a/energy_usage/__init__.py b/energy_usage/__init__.py new file mode 100644 index 0000000..5feb3e1 --- /dev/null +++ b/energy_usage/__init__.py @@ -0,0 +1 @@ +name = "energy_usage" diff --git a/energy-meter/convert.py b/energy_usage/convert.py similarity index 100% rename from energy-meter/convert.py rename to energy_usage/convert.py diff --git a/data/README.md b/energy_usage/data/README.md similarity index 100% rename from data/README.md rename to energy_usage/data/README.md diff --git a/data/csv/emissions-us.csv b/energy_usage/data/csv/emissions-us.csv similarity index 100% rename from data/csv/emissions-us.csv rename to energy_usage/data/csv/emissions-us.csv diff --git a/data/csv/energy-mix-intl.csv b/energy_usage/data/csv/energy-mix-intl.csv similarity index 100% rename from data/csv/energy-mix-intl.csv rename to energy_usage/data/csv/energy-mix-intl.csv diff --git a/data/csv/energy-mix-us.csv b/energy_usage/data/csv/energy-mix-us.csv similarity index 100% rename from data/csv/energy-mix-us.csv rename to energy_usage/data/csv/energy-mix-us.csv diff --git a/data/json/energy-mix-intl.json b/energy_usage/data/json/energy-mix-intl.json similarity index 100% rename from data/json/energy-mix-intl.json rename to energy_usage/data/json/energy-mix-intl.json diff --git a/data/json/energy-mix-us.json b/energy_usage/data/json/energy-mix-us.json similarity index 100% rename from data/json/energy-mix-us.json rename to energy_usage/data/json/energy-mix-us.json diff --git a/data/json/us-emissions.json b/energy_usage/data/json/us-emissions.json similarity index 100% rename from data/json/us-emissions.json rename to energy_usage/data/json/us-emissions.json diff --git a/energy-meter/energy-meter.py b/energy_usage/energy-meter.py similarity index 92% rename from energy-meter/energy-meter.py rename to energy_usage/energy-meter.py index d019781..f0a14b7 100644 --- a/energy-meter/energy-meter.py +++ b/energy_usage/energy-meter.py @@ -1,3 +1,5 @@ +#import energy_usage.evaluate as evaluate +from . import evaluate import evaluate import time diff --git a/energy-meter/evaluate.py b/energy_usage/evaluate.py similarity index 88% rename from energy-meter/evaluate.py rename to energy_usage/evaluate.py index f264a16..cd52aa2 100644 --- a/energy-meter/evaluate.py +++ b/energy_usage/evaluate.py @@ -6,18 +6,18 @@ import datetime import subprocess -import utils -import convert -import locate +import energy_usage.utils as utils +import energy_usage.convert as convert +import energy_usage.locate as locate DELAY = .1 # in seconds - def func(user_func, q, *args): + """ Runs the user's function and gets return value """ + value = user_func(*args) q.put(value) - def energy(user_func, *args): """ Evaluates the kwh needed for your code to run @@ -28,23 +28,8 @@ def energy(user_func, *args): baseline_checks_in_seconds = 2 files, multiple_cpus = utils.get_files() - - #packages = utils.get_packages() - # Get baseline wattage reading (FOR WHAT? PKG for now, DELAY? default .1 second) - # GPU handling if Nvidia - is_nvidia_gpu = True - try: - bash_command = "nvidia-smi > /dev/null 2>&1" #we must pipe to ignore error message - output = subprocess.check_call(['bash','-c', bash_command]) - if "GPU" not in files: - files.append(RAPLFile("GPU", "")) - bash_command = "nvidia-smi --query-gpu=,power.draw --format=csv,noheader,nounits" - - except: - is_nvidia_gpu = False - - + is_nvidia_gpu = utils.valid_gpu() for i in range(int(baseline_checks_in_seconds / DELAY)): if is_nvidia_gpu: @@ -72,7 +57,6 @@ def energy(user_func, *args): files = utils.measure_files(files, DELAY) files = utils.update_files(files, True) - package = utils.get_total(files, multiple_cpus) if package >=0: utils.log("Process wattage", package) @@ -115,7 +99,7 @@ def energy_mix(location): if location == "Unknown": location = "United States" - data = utils.get_data("../data/json/energy-mix-us.json") + data = utils.get_data("data/json/energy-mix-us.json") s = data[location]['mix'] # get state coal, oil, gas = s['coal'], s['oil'], s['gas'] nuclear, hydro, biomass, wind, solar, geo, = \ @@ -128,7 +112,7 @@ def energy_mix(location): return breakdown # list of % of each else: - data = utils.get_data('../data/json/energy-mix-intl.json') + data = utils.get_data('data/json/energy-mix-intl.json') c = data[location] # get country total, breakdown = c['total'], [c['coal'], c['naturalGas'], \ c['petroleum'], c['lowCarbon']] @@ -164,7 +148,7 @@ def emissions(process_kwh, breakdown, location): if location == "Unknown": location = "United States" # US Emissions data is in lbs/Mwh - data = utils.get_data("../data/json/us-emissions.json") + data = utils.get_data("data/json/us-emissions.json") emission = convert.lbs_to_kgs(data[location]*convert.to_Mwh(process_kwh)) # Case 3: International location diff --git a/energy-meter/locate.py b/energy_usage/locate.py similarity index 99% rename from energy-meter/locate.py rename to energy_usage/locate.py index 13ea5d4..a0d8d3a 100644 --- a/energy-meter/locate.py +++ b/energy_usage/locate.py @@ -37,6 +37,5 @@ def get(): print("Location: {:>70}".format(location)) return location - def in_US(location): return (location in STATES or location == "United States") diff --git a/energy-meter/utils.py b/energy_usage/utils.py similarity index 91% rename from energy-meter/utils.py rename to energy_usage/utils.py index 521ab9b..ccb1504 100644 --- a/energy-meter/utils.py +++ b/energy_usage/utils.py @@ -7,29 +7,17 @@ import re import statistics -import convert -import locate -from RAPLFile import RAPLFile +import energy_usage.convert as convert +import energy_usage.locate as locate +from energy_usage.RAPLFile import RAPLFile # TO DO: Function to convert seconds into more reasonable time # TO DO: Having something to relate to - -# MSR_*FILE*_ENERGY_STATUS -# Total amount of energy consumed since that last time this register was -# cleared BASE = "/sys/class/powercap/" - -PKG = "/sys/class/powercap/intel-rapl:0/energy_uj" -CORE = "/sys/class/powercap/intel-rapl:0:0/energy_uj" -UNCORE = "/sys/class/powercap/intel-rapl:0:1/energy_uj" -DRAM = "/sys/class/powercap/intel-rapl:1:0/energy_uj"# if has_multiple_cpus() \ - #else "/sys/class/powercap/intel-rapl:0:2/energy_uj" - DELAY = .1 # in seconds DIR_PATH = os.path.dirname(os.path.realpath(__file__)) - """ MEASUREMENT UTILS """ def read(file): @@ -55,6 +43,7 @@ def measure(file, delay=1): end = read(file) return end-start + def get_process_average(raplfiles, multiple_cpus): total = 0 if multiple_cpus: @@ -67,6 +56,7 @@ def get_process_average(raplfiles, multiple_cpus): if file.name == "Package": return file.process_average return -1 + def get_baseline_average(raplfiles, multiple_cpus): total = 0 if multiple_cpus: @@ -78,7 +68,7 @@ def get_baseline_average(raplfiles, multiple_cpus): for file in raplfiles: if file.name == "Package": return file.baseline_average - return -1 + def get_total(raplfiles, multiple_cpus): total = 0 @@ -91,7 +81,7 @@ def get_total(raplfiles, multiple_cpus): for file in raplfiles: if file.name == "Package": return file.recent - return -1 + def update_files(raplfiles, process = False): if process: @@ -105,7 +95,6 @@ def update_files(raplfiles, process = False): return raplfiles - def start(raplfile): measurement = read(raplfile.path) raplfile.recent = measurement @@ -130,8 +119,7 @@ def measure_files(files, delay = 1): files = list(map(start, files)) time.sleep(delay) - # need lambda to pass in delay - files = list(map(lambda x: end(x, delay), files)) + files = list(map(lambda x: end(x, delay), files)) # need lambda to pass in delay return files @@ -165,7 +153,7 @@ def get_files(): for file in files: if (re.fullmatch("intel-rapl:.", file)): cpu_count += 1 - + if cpu_count > 1: multiple_cpus = True @@ -184,13 +172,6 @@ def get_files(): return filenames, multiple_cpus - -def has_multiple_cpus(): - - packages = get_packages() - return len(packages) > 1 - - # from realpython.com/python-rounding def round_up(n, decimals=4): """ Rounds up if digit is >= 5 """ @@ -277,7 +258,6 @@ def log(*args): sys.stdout.write("{:<14} {:>65}\n".format("Natural gas:", ".0885960 kg CO2/kwh")) - """ MISC UTILS """ def get_data(file): @@ -290,10 +270,7 @@ def valid_cpu(): return os.path.exists(BASE) and bool(os.listdir(BASE)) def valid_gpu(): - - # checks that there is a valid gpu: either integrated graphics - # or nvidia - + """ Checks that there is a valid Nvidia GPU """ try: bash_command = "nvidia-smi > /dev/null 2>&1" #we must pipe to ignore error message output = subprocess.check_call(['bash','-c', bash_command]) diff --git a/requirements.txt b/requirements.txt index 091aa48..3288e92 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ requests -reportlab + diff --git a/setup.py b/setup.py index 2fa86fa..54adb85 100644 --- a/setup.py +++ b/setup.py @@ -3,16 +3,17 @@ with open("README.md", "r") as fh: long_description = fh.read() -NAME = "energy-usage" +NAME = "energy_usage" VERSION = "0.0.1" DESCRIPTION = "Measuring the environmental impact of computation" LONG_DESCRIPTION = long_description URL = "https://github.com/responsibleproblemsolving/energy-usage" -AUTHOR = "Silvia Susai, Kadan Lottick" -AUTHOR_EMAIL = "@haverford.edu" +AUTHOR = "Sorelle Friedler, Kadan Lottick, Silvia Susai" +AUTHOR_EMAIL = "sorelle@cs.haverford.edu" + LICENSE = "Apache 2.0" CLASSIFIERS = [ @@ -21,32 +22,30 @@ "Operating System :: OS Independent", ] -PACKAGES = find_packages() +PACKAGES = ['energy_usage'] + PACKAGE_DATA = { - 'energy.data.csv' : ['*.csv'] - 'energy.data.json' : ['*.json'] + 'energy_usage.data.csv' : ['*.csv'], + 'energy_usage.data.json' : ['*.json'] } INCLUDE_PACKAGE_DATA = True + PACKAGE_DIR = { - 'energy.data' : 'energy/data' + 'energy_usage.data' : 'data' } INSTALL_REQUIRES = [ 'requests' ] - - - setup( name= NAME, version=VERSION, description=DESCRIPTION, long_description=LONG_DESCRIPTION, - long_description_content_type="text/markdown", url=URL, author=AUTHOR, - author_email=AUTHOR_EMAIL, + author_email = AUTHOR_EMAIL, license = LICENSE, classifiers=CLASSIFIERS, packages = PACKAGES,