Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
ArneTR committed Jun 13, 2024
1 parent 95f6e88 commit 7c8bdee
Show file tree
Hide file tree
Showing 12 changed files with 179 additions and 127 deletions.
16 changes: 10 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,27 @@ permissions:

jobs:
test-action:
runs-on: ubuntu-latest
runs-on: ${matrix.os}
continue-on-error: false
strategy:
fail-fast: true
matrix:
os: [ubuntu-latest, ubuntu-24.04, ubuntu-20.04, ubuntu-18.04, ubuntu-20.04-16core]
# It might be the case
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.ref }}

- name: actions/checkout@v3
- name: API Base Debug
run: |
echo "Current API Base is" ${{ github.api_url }}
- name: Initialize Energy Estimation
uses: ./
with:
task: start-measurement



- name: Sleep step
run: sleep 2

Expand All @@ -48,7 +51,8 @@ jobs:
label: "Sleep 3s"

- name: Filesystem
run: ls -alhR /usr/lib
run: timeout 10s ls -alhR /usr/lib
continue-on-error: true

- name: Test measurement 2
uses: ./
Expand Down
4 changes: 4 additions & 0 deletions .gitlab-ci.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ test-job:
#- export ECO_CI_PROJECT_UUID="YOUR PROJECT UUID"
#- export ECO_CI_MACHINE_UUID="YOUR MACHINE UUID"

# Change this to you machine, if you are not using the default.
# https://docs.gitlab.com/ee/ci/runners/hosted_runners/linux.html
#- export MACHINE_POWER_DATA="gitlab_EPYC_7B12_saas-linux-small-amd64.txt"

- !reference [.initialize_energy_estimator, script]
- !reference [.start_measurement, script]
- sleep 10s
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ test-job:
+ The plugin is tested on:
+ `ubuntu-latest` (22.04 at the time of writing)
+ `ubuntu-24.04`
+ [Autoscaling Github Runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-larger-runners/managing-larger-runners#configuring-autoscaling-for-larger-runners) are not supported
+ It is known to not work on `ubuntu-20.04` ([See here](https://github.com/green-coding-solutions/eco-ci-energy-estimation/issues/72))
+ Also Windows and macOS are currently not supported.

Expand Down
16 changes: 10 additions & 6 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ inputs:
description: 'Label for the get-measurement task, to mark what this measurement correlates to in your workflow'
default: null
required: false
machine-power-data:
description: 'The file to read the machine power data from. Default will be 4 core AMD EPYC 7763 Github Runner'
default: "github_EPYC_7763_4_CPU_shared.sh"
required: false
send-data:
description: 'Send metrics data to metrics.green-coding.io to create and display badge, and see an overview of the energy of your CI runs. Set to false to send no data.'
default: true
Expand All @@ -35,7 +39,7 @@ inputs:
pr-comment:
description: 'Add a comment to the PR with the results during display-results step'
default: false
api-base:
gh-api-base:
description: 'Base URL of the Github API to send data to. Default is api.github.com, but can be changed to your hostname if you have Github Enterprise'
default: ${{ github.api_url }}
required: false
Expand Down Expand Up @@ -75,7 +79,7 @@ runs:
name: Setup
shell: bash
run: |
# call the initialize function of setup.sh
${{github.action_path}}/scripts/vars.sh add_var "MACHINE_POWER_DATA" "${{inputs.machine-power-data}}"
${{github.action_path}}/scripts/setup.sh initialize
- if: inputs.task == 'start-measurement'
Expand All @@ -85,7 +89,7 @@ runs:
# we prefer this over manual startint / stopping as it is less error prone for users
run: |
if ${{inputs.send-data}}; then
curl_response=$(curl -s -H "Authorization: Bearer ${{github.token}}" ${{ inputs.api-base }}/repos/${{ github.repository }}/actions/workflows)
curl_response=$(curl -s -H "Authorization: Bearer ${{github.token}}" ${{ inputs.gh-api-base }}/repos/${{ github.repository }}/actions/workflows)
workflow_id=$(echo $curl_response | jq '.workflows[] | select(.name == "${{ github.workflow }}") | .id')
${{github.action_path}}/scripts/vars.sh add_var "WORKFLOW_ID" $workflow_id
else
Expand Down Expand Up @@ -124,7 +128,7 @@ runs:
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
COMMENTS=$(curl -s -H "Authorization: Bearer ${{github.token}}" "${{ inputs.api-base }}/repos/${{ github.repository }}/issues/$PR_NUMBER/comments")
COMMENTS=$(curl -s -H "Authorization: Bearer ${{github.token}}" "${{ inputs.gh-api-base }}/repos/${{ github.repository }}/issues/$PR_NUMBER/comments")
echo "$COMMENTS" | jq -c --arg username "github-actions[bot]" '.[] | select(.user.login == $username and (.body | index("Eco-CI") // false))' | while read -r comment; do
COMMENT_ID=$(echo "$comment" | jq -r '.id')
Expand All @@ -137,12 +141,12 @@ runs:
$INNER_BODY
</details>" '{"body": $body}')
curl -s -H "Authorization: Bearer ${{github.token}}" -X PATCH -d "$PAYLOAD" "${{ inputs.api-base }}/repos/${{ github.repository }}/issues/comments/$COMMENT_ID"
curl -s -H "Authorization: Bearer ${{github.token}}" -X PATCH -d "$PAYLOAD" "${{ inputs.gh-api-base }}/repos/${{ github.repository }}/issues/comments/$COMMENT_ID"
echo "Comment $COMMENT_ID collapsed."
done
NEW_COMMENT=$(cat "/tmp/eco-ci/output-pr.txt" | jq -Rs '.')
API_URL="${{ inputs.api-base }}/repos/${{ github.repository }}/issues/${PR_NUMBER}/comments"
API_URL="${{ inputs.gh-api-base }}/repos/${{ github.repository }}/issues/${PR_NUMBER}/comments"
curl -X POST -H "Authorization: Bearer ${{github.token}}" -d @- $API_URL <<EOF
{
"body": $NEW_COMMENT
Expand Down
4 changes: 4 additions & 0 deletions eco-ci-gitlab.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ variables:
if [[ -d /tmp/eco-ci ]]; then
rm -rf /tmp/eco-ci
fi
if [[ -n $MACHINE_POWER_DATA ]]; then
/tmp/eco-ci/main/scripts/vars.sh add_var "MACHINE_POWER_DATA" "gitlab_EPYC_7B12_saas-linux-small-amd64.txt"
fi
.start_measurement:
script:
- |
Expand Down
9 changes: 5 additions & 4 deletions github_EPYC_7763.sh → github_EPYC_7763_4_CPU_shared.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#!/usr/bin/env sh
declare -A my_hashmap=( \
["0.0"]="1.7586170434951782" \
["5.0"]="3.442734718322754" \
#!/usr/bin/env bash
declare -A cloud_energy_hashmap=( \
[0.0]= "1.7586170434951782" \
[5.0]= "3.442734718322754" \
)
["10.0"]="3.617241621017456" \
["15.0"]="3.791748523712158" \
["20.0"]="3.9246811866760254" \
Expand Down
File renamed without changes.
20 changes: 10 additions & 10 deletions scripts/display_results.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ function display_results {
MEASUREMENT_RAN=${MEASUREMENT_RAN:-}
MEASUREMENT_COUNT=${MEASUREMENT_COUNT:-}
WORKFLOW_ID=${WORKFLOW_ID:-}
API_BASE=${API_BASE:-}
DASHBOARD_API_BASE=${DASHBOARD_API_BASE:-}
MACHINE_POWER_HASHMAP=${MACHINE_POWER_HASHMAP:-}
MACHINE_POWER_DATA=${MACHINE_POWER_DATA:-}


output="/tmp/eco-ci/output.txt"
output_pr="/tmp/eco-ci/output-pr.txt"

if [[ $MEASUREMENT_RAN != true ]]; then
echo "Running a measurement to have at least one result to display."
while read -r time util; do
echo "$time * $util" | bc -l >> /tmp/eco-ci/energy-total.txt
done < /tmp/eco-ci/cpu-util-total.txt
max_measurement_number=1
if [[ $(wc -l < /tmp/eco-ci/energy-total.txt) -gt 0 ]]; then
echo "Could not display table as no measurement data was present!"
echo "Could not display table as no measurement data was present!" >> $GITHUB_STEP_SUMMARY
return 1
fi

cpu_avg=$(awk '{ total += $2; count++ } END { print total/count }' /tmp/eco-ci/cpu-util-total.txt)
Expand Down Expand Up @@ -95,8 +95,8 @@ function display_results {
branch_enc=$( echo ${branch} | jq -Rr @uri)

if [[ ${show_carbon} == 'true' ]]; then
source "$(dirname "$0")/vars.sh" get_energy_co2 "$total_energy"
source "$(dirname "$0")/vars.sh" get_embodied_co2 "$total_time"
source "$(dirname "$0")/misc.sh" get_energy_co2 "$total_energy"
source "$(dirname "$0")/misc.sh" get_embodied_co2 "$total_time"


if [ -n "$CO2EQ_EMBODIED" ] && [ -n "$CO2EQ_ENERGY" ]; then # We only check for co2 as if this is set the others should be set too
Expand All @@ -117,7 +117,7 @@ function display_results {


if [[ ${send_data} == 'true' && ${display_badge} == 'true' ]]; then
get_endpoint=$API_BASE"/v1/ci/measurement/get"
get_endpoint=$DASHBOARD_API_BASE"/v1/ci/measurement/get"
metrics_url="https://metrics.green-coding.io"

echo "Badge for your README.md:" >> $output
Expand Down
23 changes: 16 additions & 7 deletions scripts/make_measurement.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ function make_measurement() {
MODEL_NAME=${MODEL_NAME:-}
MEASUREMENT_COUNT=${MEASUREMENT_COUNT:-}
WORKFLOW_ID=${WORKFLOW_ID:-}
API_BASE=${API_BASE:-}
DASHBOARD_API_BASE=${DASHBOARD_API_BASE:-}
MACHINE_POWER_HASHMAP=${MACHINE_POWER_HASHMAP:-}
MACHINE_POWER_DATA=${MACHINE_POWER_DATA:-}



Expand All @@ -30,10 +32,18 @@ function make_measurement() {
# check wc -l of cpu-util is greater than 0
if [[ $(wc -l < /tmp/eco-ci/cpu-util-temp.txt) -gt 0 ]]; then

while read -r time util; do
echo "$time * $util" | bc -l >> /tmp/eco-ci/energy-step.txt
done < /tmp/eco-ci/cpu-util-temp.txt

if [[ $MACHINE_POWER_HASHMAP == "" ]]; then
echo "Using bash mode inference"
while read -r time util; do
echo "$time * ${MACHINE_POWER_HASHMAP[$util]}" | bc -l >> /tmp/eco-ci/energy-step.txt
done < /tmp/eco-ci/cpu-util-temp.txt
else
echo "Using legacy mode inference"
while read -r time util; do
power_value=$(awk -F "=" -v pattern="[$util]" '{ if ($1 == pattern) print $2 }' $MACHINE_POWER_DATA)
echo "$time * ${power_value}" | bc -l >> /tmp/eco-ci/energy-step.txt
done < /tmp/eco-ci/cpu-util-temp.txt
fi

if [[ $MEASUREMENT_COUNT == '' ]]; then
MEASUREMENT_COUNT=1
Expand All @@ -56,7 +66,6 @@ function make_measurement() {
source "$(dirname "$0")/vars.sh" add_var $key_to_add "$value_to_add"

echo $total_energy >> /tmp/eco-ci/energy-values.txt
source "$(dirname "$0")/vars.sh" add_var MEASUREMENT_RAN true

if [[ $send_data == 'true' ]]; then

Expand All @@ -65,7 +74,7 @@ function make_measurement() {

CO2EQ=$(echo "$CO2EQ_EMBODIED + $CO2EQ_ENERGY" | bc -l)

add_endpoint=$API_BASE"/v1/ci/measurement/add"
add_endpoint=$DASHBOARD_API_BASE"/v1/ci/measurement/add"
value_mJ=$(echo "$total_energy*1000" | bc -l | cut -d '.' -f 1)
unit="mJ"
model_name_uri=$(echo $MODEL_NAME | jq -Rr @uri)
Expand Down
105 changes: 105 additions & 0 deletions scripts/misc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#!/usr/bin/env sh
set -euo pipefail

get_geo_ipapi_co() {
response=$(curl -s https://ipapi.co/json || true)

if [[ -z "$response" ]] || ! echo "$response" | jq empty; then
echo "Failed to retrieve data or received invalid JSON. Exiting" >&2
return
fi

if echo "$response" | jq '.latitude, .longitude, .city' | grep -q null; then
echo "Required data is missing. Exiting" >&2
return
fi

echo "$response"
}

get_carbon_intensity() {
latitude=$1
longitude=$2

if [ -z "${ELECTRICITY_MAPS_TOKEN+x}" ]; then
export ELECTRICITY_MAPS_TOKEN='no_token'
fi

response=$(curl -s -H "auth-token: $ELECTRICITY_MAPS_TOKEN" "https://api.electricitymap.org/v3/carbon-intensity/latest?lat=$latitude&lon=$longitude" || true)

if [[ -z "$response" ]] || ! echo "$response" | jq empty; then
echo "Failed to retrieve data or received invalid JSON. Exiting" >&2
return
fi

if echo "$response" | jq '.carbonIntensity' | grep -q null; then
echo "Required carbonIntensity is missing. Exiting" >&2
return
fi

echo "$response" | jq '.carbonIntensity'
}

get_embodied_co2_val (){
time=$1

if [ -n "$SCI_M" ]; then
co2_value=$(echo "$SCI_M * ($time/$SCI_USAGE_DURATION)" | bc -l)
export CO2EQ_EMBODIED="$co2_value"
else
echo "SCI_M was not set" >&2
fi

}

get_energy_co2_val (){
total_energy=$1

geo_data=$(get_geo_ipapi_co) || true
if [ -n "$geo_data" ]; then
latitude=$(echo "$geo_data" | jq '.latitude')
longitude=$(echo "$geo_data" | jq '.longitude')
city=$(echo "$geo_data" | jq -r '.city')

export CITY="$city"
export LAT="$latitude"
export LON="$longitude"

carbon_intensity=$(get_carbon_intensity $latitude $longitude) || true

if [[ -n "$carbon_intensity" ]]; then
export CO2I="$carbon_intensity"

value_mJ=$(echo "$total_energy*1000" | bc -l | cut -d '.' -f 1)
value_kWh=$(echo "$value_mJ * 10^-9" | bc -l)
co2_value=$(echo "$value_kWh * $carbon_intensity" | bc -l)

export CO2EQ_ENERGY="$co2_value"

else
echo "Failed to get carbon intensity data." >&2
fi
else
echo "Failed to get geolocation data." >&2
fi
}

# Main script logic
if [ $# -eq 0 ]; then
echo "No option provided. Please specify an option to misc.sh"
exit 1
fi

option="$1"
case $option in
get_energy_co2)
get_energy_co2_val $2
;;
get_embodied_co2)
get_embodied_co2_val $2
;;
*)
echo "Invalid option ($option). Please specify a valid option to misc.sh"
exit 1
;;
esac
7 changes: 6 additions & 1 deletion scripts/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ function initialize {
fi
# call init_variables
source "$(dirname "$0")/vars.sh" cpu_vars
source "$(dirname "$0")/vars.sh" add_var API_BASE "https://api.green-coding.io"
source "$(dirname "$0")/vars.sh" add_var DASHBOARD_API_BASE "https://api.green-coding.io"

if [[ -n "$BASH_VERSION" ]] && (( ${BASH_VERSION:0:1} >= 4 )); then
source "$(dirname "$0")/machine-power-data/${MACHINE_POWER_DATA}"
source "$(dirname "$0")/vars.sh" add_var MACHINE_POWER_HASHMAP $cloud_energy_hashmap
fi
}


Expand Down
Loading

0 comments on commit 7c8bdee

Please sign in to comment.