Energy Measurement¶
Measure energy consumption of your analysis workloads with RAPL and CodeCarbon.
Overview¶
GreenMining includes energy measurement capabilities to profile the power consumption of analysis operations. This is useful for:
- Research - Quantify energy cost of mining operations
- Optimization - Identify energy-intensive analysis steps
- Reporting - Include energy metrics in analysis reports
Supported Backends¶
| Backend | Platform | Features |
|---|---|---|
| RAPL | Linux (Intel/AMD) | Direct CPU/DRAM power reading |
| CodeCarbon | Cross-platform | Emissions tracking, cloud support |
| CPU Energy Meter | All platforms | Utilization-based estimation |
| Auto | All platforms | RAPL if available, else CPU Meter |
RAPL Backend¶
Intel's Running Average Power Limit (RAPL) provides direct power measurements on Linux systems with Intel or AMD processors.
Requirements¶
- Linux operating system
- Intel Core 2nd generation+ or AMD Ryzen
- Read access to
/sys/class/powercap/intel-rapl/
Checking Availability¶
from greenmining.energy.rapl import RAPLEnergyMeter
meter = RAPLEnergyMeter()
if meter.is_available():
print("RAPL is available on this system")
else:
print("RAPL not available - try running as root")
Basic Usage¶
from greenmining.energy.rapl import RAPLEnergyMeter
meter = RAPLEnergyMeter()
# Start measurement
meter.start()
# Your workload here
result = expensive_computation()
# Stop and get metrics
metrics = meter.stop()
print(f"Energy consumed: {metrics.energy_joules:.2f} J")
print(f"Duration: {metrics.duration_seconds:.2f} s")
print(f"Average power: {metrics.average_power_watts:.2f} W")
With Context Manager¶
from greenmining.energy.rapl import RAPLEnergyMeter
meter = RAPLEnergyMeter()
with meter.measure() as measurement:
# Your analysis code
analyzer.analyze_repository(repo_url)
print(f"Analysis consumed {measurement.energy_joules:.2f} J")
Permission Setup¶
RAPL typically requires root access. To allow non-root users:
# Grant read access to RAPL files
sudo chmod a+r /sys/class/powercap/intel-rapl/intel-rapl:0/energy_uj
sudo chmod a+r /sys/class/powercap/intel-rapl/intel-rapl:0/intel-rapl:0:*/energy_uj
# Or create a udev rule for persistent access
echo 'SUBSYSTEM=="powercap", ACTION=="add", RUN+="/bin/chmod a+r /sys/class/powercap/intel-rapl/intel-rapl:0/energy_uj"' | sudo tee /etc/udev/rules.d/99-rapl.rules
CodeCarbon Backend¶
CodeCarbon tracks energy consumption and CO2 emissions across platforms.
Installation¶
Basic Usage¶
from greenmining.energy.codecarbon_meter import CodeCarbonMeter
meter = CodeCarbonMeter(
country_iso_code="USA", # For carbon intensity
project_name="greenmining-analysis",
tracking_mode="process" # or "machine"
)
# Start tracking
meter.start()
# Your workload
result = analyzer.analyze_repository(repo_url)
# Stop and get metrics
metrics = meter.stop()
print(f"Energy: {metrics.energy_kwh:.6f} kWh")
print(f"CO2 emissions: {metrics.emissions_kg:.6f} kg")
print(f"Duration: {metrics.duration_seconds:.2f} s")
Configuration Options¶
meter = CodeCarbonMeter(
country_iso_code="FRA", # France
region="ile-de-france", # Optional region
project_name="my-analysis",
output_dir="./energy_logs", # Where to save logs
save_to_file=True, # Save detailed logs
tracking_mode="process" # process or machine
)
Carbon Tracking¶
from greenmining.energy.codecarbon_meter import CodeCarbonMeter
meter = CodeCarbonMeter(project_name="greenmining")
meter.start()
# ... analysis ...
metrics = meter.stop()
print(f"Energy: {metrics.energy_joules:.2f} J")
print(f"Carbon footprint: {metrics.carbon_grams:.4f} g CO2")
CPU Energy Meter¶
Cross-platform energy estimation using CPU utilization and TDP modeling.
Basic Usage¶
from greenmining.energy import CPUEnergyMeter
meter = CPUEnergyMeter()
meter.start()
# Your workload
result = expensive_computation()
metrics = meter.stop()
print(f"Estimated energy: {metrics.joules:.2f} J")
print(f"Average power: {metrics.watts_avg:.2f} W")
Custom TDP¶
from greenmining.energy import CPUEnergyMeter
# Specify your CPU's TDP for more accurate estimation
meter = CPUEnergyMeter(tdp_watts=45.0) # e.g., laptop CPU
Auto-Detection¶
from greenmining.energy import get_energy_meter
# Automatically selects RAPL (if available) or CPU Meter
meter = get_energy_meter("auto")
meter.start()
# ... workload ...
metrics = meter.stop()
Integrated Energy Tracking¶
Automatically measure energy during repository analysis.
from greenmining.services.local_repo_analyzer import LocalRepoAnalyzer
analyzer = LocalRepoAnalyzer(
energy_tracking=True,
energy_backend="auto", # rapl, codecarbon, cpu_meter, auto
)
result = analyzer.analyze_repository("https://github.com/pallets/flask")
print(f"Energy consumed: {result.energy_metrics['joules']:.2f} J")
print(f"Average power: {result.energy_metrics['watts_avg']:.2f} W")
print(f"Duration: {result.energy_metrics['duration_seconds']:.2f} s")
Carbon Footprint Reporting¶
Convert energy measurements to CO2 emissions using regional carbon intensity data.
Basic Usage¶
from greenmining.energy import CarbonReporter
reporter = CarbonReporter(country_iso="USA")
report = reporter.generate_report(total_joules=3600.0)
print(f"CO2: {report.total_emissions_kg * 1000:.4f} grams")
print(f"Equivalent to {report.tree_months:.2f} tree-months")
print(f"Or {report.smartphone_charges:.1f} smartphone charges")
Cloud Region Support¶
from greenmining.energy import CarbonReporter
# Use cloud provider region for accurate carbon intensity
reporter = CarbonReporter(
country_iso="USA",
cloud_provider="aws",
region="eu-north-1", # Stockholm - low carbon (renewable energy)
)
report = reporter.generate_report(total_joules=1000.0)
print(report.summary())
Supported Regions¶
from greenmining.energy import CarbonReporter
# 20+ country profiles
countries = CarbonReporter.get_supported_countries()
# AWS, GCP, Azure regions
aws_regions = CarbonReporter.get_supported_cloud_regions("aws")
gcp_regions = CarbonReporter.get_supported_cloud_regions("gcp")
Energy Metrics¶
EnergyMetrics Class¶
from greenmining.energy.base import EnergyResult
@dataclass
class EnergyResult:
energy_joules: float # Total energy in Joules
duration_seconds: float # Measurement duration
average_power_watts: float # Average power draw
start_time: datetime # Measurement start
end_time: datetime # Measurement end
# CodeCarbon specific
energy_kwh: float = 0.0 # Energy in kilowatt-hours
emissions_kg: float = 0.0 # CO2 emissions in kg
CommitEnergyProfile¶
Track energy per commit analysis:
from greenmining.energy.base import CommitEnergyProfile
@dataclass
class CommitEnergyProfile:
commit_sha: str
energy_joules: float
duration_seconds: float
patterns_detected: list
files_analyzed: int
Research Applications¶
Measuring Analysis Efficiency¶
from greenmining.energy.rapl import RAPLEnergyMeter
from greenmining.services.local_repo_analyzer import LocalRepoAnalyzer
meter = RAPLEnergyMeter()
analyzer = LocalRepoAnalyzer()
repos = [
"https://github.com/pallets/flask",
"https://github.com/django/django",
]
results = []
for url in repos:
meter.start()
analysis = analyzer.analyze_repository(url, max_commits=100)
energy = meter.stop()
results.append({
"repo": url,
"commits": analysis["total_commits"],
"energy_joules": energy.energy_joules,
"joules_per_commit": energy.energy_joules / analysis["total_commits"]
})
# Compare efficiency
for r in results:
print(f"{r['repo']}: {r['joules_per_commit']:.3f} J/commit")
Energy-Aware Batch Processing¶
from greenmining.energy.rapl import RAPLEnergyMeter
meter = RAPLEnergyMeter()
energy_budget_joules = 1000 # Set energy budget
total_energy = 0
analyzed_repos = []
for repo in repositories:
meter.start()
result = analyze(repo)
metrics = meter.stop()
total_energy += metrics.energy_joules
analyzed_repos.append(repo)
if total_energy >= energy_budget_joules:
print(f"Energy budget reached after {len(analyzed_repos)} repos")
break
Comparing Backends¶
| Feature | RAPL | CodeCarbon | CPU Meter |
|---|---|---|---|
| Accuracy | High (hardware) | Medium (estimation) | Low (model) |
| Platform | Linux only | Cross-platform | All platforms |
| Granularity | Microseconds | Seconds | Seconds |
| CO2 tracking | No | Yes | Via CarbonReporter |
| Cloud support | No | Yes | Via CarbonReporter |
| Setup | May need root | pip install | No setup |
Recommendation¶
- Use RAPL for precise measurements on Linux
- Use CodeCarbon for cross-platform and carbon tracking
- Use CPU Meter when neither RAPL nor CodeCarbon is available
- Use auto to let GreenMining pick the best available backend
Troubleshooting¶
RAPL Not Available¶
# Check if RAPL files exist
import os
rapl_path = "/sys/class/powercap/intel-rapl/intel-rapl:0/energy_uj"
print(f"RAPL exists: {os.path.exists(rapl_path)}")
# Check permissions
if os.path.exists(rapl_path):
print(f"Readable: {os.access(rapl_path, os.R_OK)}")
CodeCarbon Import Error¶
# Install with all dependencies
pip install codecarbon[viz]
# Or minimal install
pip install codecarbon
Virtual Machine Limitations¶
RAPL typically doesn't work in VMs. Use CodeCarbon instead:
from greenmining.energy.rapl import RAPLEnergyMeter
from greenmining.energy.codecarbon_meter import CodeCarbonMeter
# Try RAPL first, fall back to CodeCarbon
rapl = RAPLEnergyMeter()
if rapl.is_available():
meter = rapl
else:
print("RAPL not available, using CodeCarbon")
meter = CodeCarbonMeter()
Next Steps¶
- Python API - Full API reference
- URL Analysis - Analyze repositories by URL
- Configuration - Energy settings