Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions benchmarking/degrade/degrade_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#!/usr/bin/env python

##############################################################################
# Copyright 2021-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.
##############################################################################

from typing import TypedDict


class DegradeBase(object):
"""Base class for platform-specific "degrade" tools to be used to apply cpu or memory device constraints to a benchmark run.

The implementation-specific constraints are specified by a dictionary containing a "cpu" and / or "memory" dictionary entry.

For example:
{
"cpu": {
count: "4",
},
"memory": {
limit: "2000000KB",
}
}

This class also acts as a default no-op implementation in the case that no implementation is registered for a given platform.
"""

def __init__(self, platform_util, constraints=None):
"""Specify a dictionary containing "cpu" or "memory" options to a degrade tool to apply device constraints to the benchmark run

Args:
platform_util: (object) Platform-specific Device identifier object, such as adb
constraints (dict): Dictionary containing a "cpu" and / or "memory" dictionary of platform / implementation-specific device contraint options.

Notes:
The args value may also be passed to setArgs() directly if desired.

"""
self.util = platform_util
if constraints is not None:
self.specifyConstraints(constraints)

def __enter__(self):
self.applyConstraints()
return self

def __exit__(self, exc_type, exc_value, traceback):
self.resetConstraints()

def specifyConstraints(self, constraints):
"""Specify a dictionary containing "cpu" or "memory" options to a degrade tool to apply device constraints to the benchmark run

Args:
constraints (dict): Dictionary containing a "cpu" and / or "memory" dictionary of platform / implementation-specific device contraint options.

Notes:
The args value may also be passed to the constructor instead of to setArgs() if desired.
"""
pass

def applyConstraints(self):
"""Apply any cpu / memory constraints set previously"""
pass

def resetConstraints(self):
"""Reset device to defaults (remove any constraints applied previously)."""
pass

def logConstraints(self):
pass


class DegradeEntries(TypedDict):
platform: str
degrade: DegradeBase


default_degrade = DegradeBase

degrade_table: DegradeEntries = {}


def registerDegrade(platform: str, degrade: DegradeBase):
"""Register a platform-specific DegradeBase implementation.

Args:
platform (str): Name of the plaform (eg. "android", "ios").
degrade (DegradeBase): Implementaton drived from DegradeBase.
"""
global degrade_table
degrade_table[platform] = degrade


def getDegrade(platform: str) -> DegradeBase:
"""Lookup and return a registered platform-specific implementation of DegradeBase.

Args:
platform (str): Name of the plaform (eg. "android", "ios").

Returns:
A matching DegradeBase implementation or the default implementation if none.
"""
global degrade_table
global default_degrade
if platform in degrade_table:
return degrade_table[platform]

return default_degrade
26 changes: 16 additions & 10 deletions benchmarking/platforms/android/android_platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import shutil
import time

from degrade.degrade_base import DegradeBase, getDegrade
from platforms.platform_base import PlatformBase
from profilers.profilers import getProfilerByUsage
from six import string_types
Expand Down Expand Up @@ -55,6 +56,8 @@ def __init__(self, tempdir, adb, args, usb_controller=None):
self.usb_controller = usb_controller
self._setLogCatSize()
self.app = None
self.degrade_constraints = None
self.degrade: DegradeBase = getDegrade(self.type)
if self.args.set_freq:
self.util.setFrequency(self.args.set_freq)

Expand Down Expand Up @@ -112,6 +115,8 @@ def preprocess(self, *args, **kwargs):
if "app" in benchmark["model"]:
self.app = benchmark["model"]["app"]

self.degrade_constraints = benchmark["tests"][0].get("degrade")

if not self.app:
if "intent.txt" in programs:
# temporary to rename the program with adb suffix
Expand Down Expand Up @@ -152,16 +157,17 @@ def runBenchmark(self, cmd, *args, **kwargs):
# that is not the output of the command
meta = {}

# We know this command may fail. Avoid propogating this
# failure to the upstream
success = getRunStatus()
self.util.logcat("-b", "all", "-c")
setRunStatus(success, overwrite=True)
if self.app:
log, meta = self.runAppBenchmark(cmd, *args, **kwargs)
else:
log, meta = self.runBinaryBenchmark(cmd, *args, **kwargs)
return log, meta
with self.degrade(self.util, self.degrade_constraints):
# We know this command may fail. Avoid propogating this
# failure to the upstream
success = getRunStatus()
self.util.logcat("-b", "all", "-c")
setRunStatus(success, overwrite=True)
if self.app:
log, meta = self.runAppBenchmark(cmd, *args, **kwargs)
else:
log, meta = self.runBinaryBenchmark(cmd, *args, **kwargs)
return log, meta

def runAppBenchmark(self, cmd, *args, **kwargs):
arguments = self.getPairedArguments(cmd)
Expand Down