blob: 84cab37aa9d882f13d606fef3e3e671cf5a88da3 [file] [log] [blame]
# Copyright 2021 The TensorFlow Authors. All Rights Reserved.
#
# 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.
# ==============================================================================
"""Script to build the required binaries, profile their size and generate log.
"""
import argparse
import datetime
import os
import pandas as pd
import subprocess
def _build_a_binary(root_dir, binary_name, makefile_options):
os.chdir(root_dir)
params_list = [
"make", "-f", "tensorflow/lite/micro/tools/make/Makefile", binary_name
] + ["%s=%s" % (key, value) for (key, value) in makefile_options.items()]
process = subprocess.Popen(params_list,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
if process.returncode != 0:
raise RuntimeError("Building %s failed with \n\n %s" %
(" ".join(params_list), stderr.decode()))
def _profile_a_binary(root_dir, binary_name, makefile_options, build_info):
target_dir = "%s_%s_%s" % (makefile_options["TARGET"],
makefile_options["TARGET_ARCH"],
makefile_options["BUILD_TYPE"])
binary_path = os.path.join(root_dir, 'gen/', target_dir, 'bin', binary_name)
csv_path = os.path.join(root_dir, 'data/continuous_builds/size_profiling',
target_dir, "%s.csv" % binary_name)
# Run size command and extract the output
process = subprocess.Popen(["size", binary_path],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
if process.returncode != 0:
raise RuntimeError("size %s failed with \n\n %s" %
(binary_name, stderr.decode()))
output_str = stdout.decode()
df = pd.DataFrame([line.split() for line in output_str.split('\n')[1:]],
columns=list(output_str.split('\n')[0].split()))
# Append the output from the size to the CSV file
report = _create_or_read_csv(csv_path)
report.loc[len(report.index)] = [
build_info["date"], build_info['sha'], df['text'][0], df['data'][0],
df['bss'][0], df['dec'][0]
]
report.to_csv(csv_path, index=False, header=False, mode='a')
def _create_or_read_csv(csv_file_name):
if os.path.exists(csv_file_name) is not True:
csv_df = pd.DataFrame(
columns=['date', 'sha', 'text', 'data', 'bss', 'total'])
csv_df.to_csv(csv_file_name, index=False, mode='w')
csv_head = pd.read_csv(csv_file_name, index_col=False, nrows=0)
return csv_head
def _get_build_info(root_dir):
os.chdir(root_dir)
current_time = str(datetime.datetime.now())
git_process = subprocess.Popen(["git", "rev-parse", "HEAD"],
stdout=subprocess.PIPE,
cwd=root_dir)
sha, err = git_process.communicate()
if git_process.returncode != 0:
raise RuntimeError("Git failed with %s" % err.decode())
return {'date': current_time, 'sha': sha.decode().strip('\n')}
def _build_and_profile(root_dir, makefile_options, binary_names):
build_info = _get_build_info(root_dir)
for binary_name in binary_names:
_build_a_binary(root_dir, binary_name, makefile_options)
_profile_a_binary(root_dir, binary_name, makefile_options, build_info)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
default_binary_list_string = 'keyword_benchmark,baseline_memory_footprint,interpreter_memory_footprint'
parser.add_argument(
'--binary_list',
nargs='?',
const=default_binary_list_string,
default=default_binary_list_string,
help=
'binary list separated by comma (e.g. keyword_benchmark,baseline_memory_footprint)'
)
parser.add_argument('--build_type',
nargs='?',
const='release',
default='release',
help='build type (e.g. release)')
parser.add_argument('--target',
nargs='?',
const='linux',
default='linux',
help='host target (e.g. linux)')
parser.add_argument('--target_arch',
nargs='?',
const='x86_64',
default='x86_64',
help='target architecture (e.g x86_64)')
args = parser.parse_args()
makefile_options = {
"BUILD_TYPE": args.build_type,
"TARGET": args.target,
"TARGET_ARCH": args.target_arch
}
binary_names = args.binary_list.split(',')
script_path = os.path.dirname(os.path.realpath(__file__))
root_dir = os.path.join(script_path, '../../../../..')
_build_and_profile(root_dir, makefile_options, binary_names)