From c0b474541a4d34c819f3a21b73f760564f5399d8 Mon Sep 17 00:00:00 2001 From: David Yastremsky Date: Mon, 29 Jul 2024 10:32:08 -0700 Subject: [PATCH 1/3] When custom profile export provided, update CSV/JSON Remove print Update docs --- src/c++/perf_analyzer/genai-perf/README.md | 5 +- .../genai_perf/export_data/csv_exporter.py | 21 ++--- .../genai_perf/export_data/json_exporter.py | 7 +- .../genai-perf/genai_perf/parser.py | 5 +- .../genai-perf/tests/test_csv_exporter.py | 41 ++++++--- .../genai-perf/tests/test_json_exporter.py | 90 ++++++++++++++++++- 6 files changed, 140 insertions(+), 29 deletions(-) diff --git a/src/c++/perf_analyzer/genai-perf/README.md b/src/c++/perf_analyzer/genai-perf/README.md index 53e510541..68b0f2166 100644 --- a/src/c++/perf_analyzer/genai-perf/README.md +++ b/src/c++/perf_analyzer/genai-perf/README.md @@ -523,8 +523,9 @@ An option to enable the generation of plots. (default: False) ##### `--profile-export-file ` The path where the perf_analyzer profile export will be generated. By default, -the profile export will be to `profile_export.json`. The genai-perf file will be -exported to `_genai_perf.csv`. For example, if the profile +the profile export will be to `profile_export.json`. The genai-perf files will be +exported to `_genai_perf.json` and +`_genai_perf.csv`. For example, if the profile export file is `profile_export.json`, the genai-perf file will be exported to `profile_export_genai_perf.csv`. (default: `profile_export.json`) diff --git a/src/c++/perf_analyzer/genai-perf/genai_perf/export_data/csv_exporter.py b/src/c++/perf_analyzer/genai-perf/genai_perf/export_data/csv_exporter.py index efbb9b754..7633187ba 100644 --- a/src/c++/perf_analyzer/genai-perf/genai_perf/export_data/csv_exporter.py +++ b/src/c++/perf_analyzer/genai-perf/genai_perf/export_data/csv_exporter.py @@ -30,8 +30,6 @@ import genai_perf.logging as logging from genai_perf.export_data.exporter_config import ExporterConfig -DEFAULT_OUTPUT_DATA_CSV = "profile_export_genai_perf.csv" - logger = logging.getLogger(__name__) @@ -65,14 +63,17 @@ def __init__(self, config: ExporterConfig): self._args = config.args def export(self) -> None: - csv_filename = self._output_dir / DEFAULT_OUTPUT_DATA_CSV - logger.info(f"Generating {csv_filename}") - - with open(csv_filename, mode="w", newline="") as csvfile: - csv_writer = csv.writer(csvfile) - self._write_request_metrics(csv_writer) - csv_writer.writerow([]) - self._write_system_metrics(csv_writer) + filename = str(self._args.profile_export_file) + if filename.endswith(".json"): + filename = filename[:-5] + filename += "_genai_perf.csv" + logger.info(f"Generating {filename}") + + with open(filename, mode="w", newline="") as f: + writer = csv.writer(f) + self._write_request_metrics(writer) + writer.writerow([]) + self._write_system_metrics(writer) def _write_request_metrics(self, csv_writer) -> None: csv_writer.writerow(self.REQUEST_METRICS_HEADER) diff --git a/src/c++/perf_analyzer/genai-perf/genai_perf/export_data/json_exporter.py b/src/c++/perf_analyzer/genai-perf/genai_perf/export_data/json_exporter.py index 2ec24fae1..2f61a7894 100644 --- a/src/c++/perf_analyzer/genai-perf/genai_perf/export_data/json_exporter.py +++ b/src/c++/perf_analyzer/genai-perf/genai_perf/export_data/json_exporter.py @@ -32,8 +32,6 @@ import genai_perf.logging as logging from genai_perf.export_data.exporter_config import ExporterConfig -DEFAULT_OUTPUT_DATA_JSON = "profile_export_genai_perf.json" - logger = logging.getLogger(__name__) @@ -52,7 +50,10 @@ def __init__(self, config: ExporterConfig): self._merge_stats_and_args() def export(self) -> None: - filename = self._output_dir / DEFAULT_OUTPUT_DATA_JSON + filename = str(self._args["profile_export_file"]) + if filename.endswith(".json"): + filename = filename[:-5] + filename += "_genai_perf.json" logger.info(f"Generating {filename}") with open(str(filename), "w") as f: f.write(json.dumps(self._stats_and_args, indent=2)) diff --git a/src/c++/perf_analyzer/genai-perf/genai_perf/parser.py b/src/c++/perf_analyzer/genai-perf/genai_perf/parser.py index 776535d15..bae4c516b 100644 --- a/src/c++/perf_analyzer/genai-perf/genai_perf/parser.py +++ b/src/c++/perf_analyzer/genai-perf/genai_perf/parser.py @@ -626,8 +626,9 @@ def _add_output_args(parser): default=Path("profile_export.json"), help="The path where the perf_analyzer profile export will be " "generated. By default, the profile export will be to profile_export.json. " - "The genai-perf file will be exported to _genai_perf.csv. " - "For example, if the profile export file is profile_export.json, the genai-perf file will be " + "The genai-perf files will be exported to _genai_perf.json and " + "_genai_perf.csv. " + "For example, if the profile export file is profile_export.json, the genai-perf CSV file will be " "exported to profile_export_genai_perf.csv.", ) diff --git a/src/c++/perf_analyzer/genai-perf/tests/test_csv_exporter.py b/src/c++/perf_analyzer/genai-perf/tests/test_csv_exporter.py index 6a60bc2dc..e27ee9b2a 100644 --- a/src/c++/perf_analyzer/genai-perf/tests/test_csv_exporter.py +++ b/src/c++/perf_analyzer/genai-perf/tests/test_csv_exporter.py @@ -24,6 +24,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import os from io import StringIO from pathlib import Path from typing import Any, List @@ -37,7 +38,7 @@ class TestCsvExporter: @pytest.fixture - def mock_read_write(self, monkeypatch: pytest.MonkeyPatch) -> List[str]: + def mock_read_write(self, monkeypatch: pytest.MonkeyPatch) -> List[tuple[str, str]]: """ This function will mock the open function for specific files. """ @@ -48,15 +49,13 @@ def mock_read_write(self, monkeypatch: pytest.MonkeyPatch) -> List[str]: def custom_open(filename, *args, **kwargs): def write(self: Any, content: str) -> int: - written_data.append(content) + print(f"Writing to {filename}") # To help with debugging failures + written_data.append((str(filename), content)) return len(content) - if str(filename) == "profile_export_genai_perf.csv": - tmp_file = StringIO() - tmp_file.write = write.__get__(tmp_file) - return tmp_file - else: - return original_open(filename, *args, **kwargs) + tmp_file = StringIO() + tmp_file.write = write.__get__(tmp_file) + return tmp_file monkeypatch.setattr("builtins.open", custom_open) @@ -115,7 +114,16 @@ def test_streaming_llm_csv_output( "Output Token Throughput (per sec),456.00\r\n", "Request Throughput (per sec),123.00\r\n", ] - returned_data = mock_read_write + expected_filename = "profile_export_genai_perf.csv" + returned_data = [ + data + for filename, data in mock_read_write + if os.path.basename(filename) == expected_filename + ] + if returned_data == []: + raise Exception( + f"Expected file {expected_filename} not found in written data." + ) assert returned_data == expected_content def test_nonstreaming_llm_csv_output( @@ -125,6 +133,9 @@ def test_nonstreaming_llm_csv_output( Collect LLM metrics from profile export data and confirm correct values are printed in csv. """ + artifacts_dir = "artifacts/model_name-openai-chat-concurrency1" + custom_filename = "custom_export.json" + expected_filename = f"{artifacts_dir}/custom_export_genai_perf.csv" argv = [ "genai-perf", "profile", @@ -134,6 +145,8 @@ def test_nonstreaming_llm_csv_output( "openai", "--endpoint-type", "chat", + "--profile-export-file", + custom_filename, ] monkeypatch.setattr("sys.argv", argv) args, _ = parser.parse_args() @@ -168,7 +181,13 @@ def test_nonstreaming_llm_csv_output( "Output Token Throughput (per sec),456.00\r\n", "Request Throughput (per sec),123.00\r\n", ] - returned_data = mock_read_write + returned_data = [ + data for filename, data in mock_read_write if filename == expected_filename + ] + if returned_data == []: + raise Exception( + f"Expected file {expected_filename} not found in written data." + ) assert returned_data == expected_content def test_embedding_csv_output( @@ -209,5 +228,5 @@ def test_embedding_csv_output( "Metric,Value\r\n", "Request Throughput (per sec),123.00\r\n", ] - returned_data = mock_read_write + returned_data = [data for _, data in mock_read_write] assert returned_data == expected_content diff --git a/src/c++/perf_analyzer/genai-perf/tests/test_json_exporter.py b/src/c++/perf_analyzer/genai-perf/tests/test_json_exporter.py index f82e59312..686dc8da3 100644 --- a/src/c++/perf_analyzer/genai-perf/tests/test_json_exporter.py +++ b/src/c++/perf_analyzer/genai-perf/tests/test_json_exporter.py @@ -25,14 +25,44 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import json +import os +from io import StringIO +from typing import Any, List import genai_perf.parser as parser +import pytest from genai_perf.export_data.exporter_config import ExporterConfig from genai_perf.export_data.json_exporter import JsonExporter class TestJsonExporter: - def test_generate_json(self, monkeypatch) -> None: + @pytest.fixture + def mock_read_write(self, monkeypatch: pytest.MonkeyPatch) -> List[tuple[str, str]]: + """ + This function will mock the open function for specific files. + """ + + written_data = [] + + original_open = open + + def custom_open(filename, *args, **kwargs): + def write(self: Any, content: str) -> int: + print(f"Writing to {filename}") + written_data.append((str(filename), content)) + return len(content) + + tmp_file = StringIO() + tmp_file.write = write.__get__(tmp_file) + return tmp_file + + monkeypatch.setattr("builtins.open", custom_open) + + return written_data + + def test_generate_json( + self, monkeypatch, mock_read_write: pytest.MonkeyPatch + ) -> None: cli_cmd = [ "genai-perf", "profile", @@ -55,6 +85,64 @@ def test_generate_json(self, monkeypatch) -> None: config.artifact_dir = args.artifact_dir json_exporter = JsonExporter(config) assert json_exporter._stats_and_args == json.loads(self.expected_json_output) + json_exporter.export() + expected_filename = "profile_export_genai_perf.json" + written_data = [ + data + for filename, data in mock_read_write + if os.path.basename(filename) == expected_filename + ] + if written_data == []: + raise Exception( + f"Expected file {expected_filename} not found in written data." + ) + assert len(written_data) == 1 + assert json.loads(written_data[0]) == json.loads(self.expected_json_output) + + def test_generate_json_custom_export( + self, monkeypatch, mock_read_write: pytest.MonkeyPatch + ) -> None: + artifacts_dir = "artifacts/gpt2_vllm-triton-vllm-concurrency1" + custom_filename = "custom_export.json" + expected_filename = f"{artifacts_dir}/custom_export_genai_perf.json" + expected_profile_filename = f"{artifacts_dir}/custom_export.json" + cli_cmd = [ + "genai-perf", + "profile", + "-m", + "gpt2_vllm", + "--backend", + "vllm", + "--streaming", + "--extra-inputs", + "max_tokens:256", + "--extra-inputs", + "ignore_eos:true", + "--profile-export-file", + custom_filename, + ] + monkeypatch.setattr("sys.argv", cli_cmd) + args, _ = parser.parse_args() + config = ExporterConfig() + config.stats = self.stats + config.args = args + config.extra_inputs = parser.get_extra_inputs_as_dict(args) + config.artifact_dir = args.artifact_dir + json_exporter = JsonExporter(config) + json_exporter.export() + written_data = [ + data for filename, data in mock_read_write if filename == expected_filename + ] + if written_data == []: + raise Exception( + f"Expected file {expected_filename} not found in written data." + ) + assert len(written_data) == 1 + expected_json_output = json.loads(self.expected_json_output) + expected_json_output["input_config"][ + "profile_export_file" + ] = expected_profile_filename + assert json.loads(written_data[0]) == expected_json_output stats = { "request_throughput": {"unit": "requests/sec", "avg": "7"}, From dffe0cddd7af0a7904d2b17e4f2b6da417e668cd Mon Sep 17 00:00:00 2001 From: Francesco Petrini Date: Mon, 29 Jul 2024 09:15:40 -0700 Subject: [PATCH 2/3] Extracted minimum changes from migration branch (#722) Migrate PA Repo w/ Minimum Client changes. Add typing Remove unused functions --- CMakeLists.txt | 4 + src/c++/library/CMakeLists.txt | 106 +++++++++++++++++- .../genai-perf/tests/test_csv_exporter.py | 6 +- .../genai-perf/tests/test_json_exporter.py | 6 +- src/python/CMakeLists.txt | 4 +- src/python/library/CMakeLists.txt | 4 +- src/python/library/setup.py | 4 +- 7 files changed, 119 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5628f0a27..752dbe79b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,9 @@ option(TRITON_ENABLE_TESTS "Include tests in build" OFF) option(TRITON_ENABLE_GPU "Enable GPU support in libraries" OFF) option(TRITON_ENABLE_ZLIB "Include ZLIB library in build" ON) +# Package Perf Analyzer with the Python Client -- Intended to be used by PA repo +option(TRITON_PACKAGE_PERF_ANALYZER "Include Perf Analyzer in pip wheel" OFF) + set(TRITON_REPO_ORGANIZATION "https://github.com/triton-inference-server" CACHE STRING "Git repository to pull from") set(TRITON_COMMON_REPO_TAG "main" CACHE STRING "Tag for triton-inference-server/common repo") set(TRITON_THIRD_PARTY_REPO_TAG "main" CACHE STRING "Tag for triton-inference-server/third_party repo") @@ -223,6 +226,7 @@ if(TRITON_ENABLE_PYTHON_HTTP OR TRITON_ENABLE_PYTHON_GRPC) -DTRITON_ENABLE_PERF_ANALYZER_OPENAI:BOOL=${TRITON_ENABLE_PERF_ANALYZER_OPENAI} -DTRITON_ENABLE_EXAMPLES:BOOL=${TRITON_ENABLE_EXAMPLES} -DTRITON_ENABLE_TESTS:BOOL=${TRITON_ENABLE_TESTS} + -DTRITON_PACKAGE_PERF_ANALYZER:BOOL=${TRITON_PACKAGE_PERF_ANALYZER} -DTRITON_ENABLE_GPU:BOOL=${TRITON_ENABLE_GPU} -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=${TRITON_INSTALL_PREFIX} diff --git a/src/c++/library/CMakeLists.txt b/src/c++/library/CMakeLists.txt index cdee03e1a..7a62971e5 100644 --- a/src/c++/library/CMakeLists.txt +++ b/src/c++/library/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2020-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -60,7 +60,58 @@ if(TRITON_ENABLE_CC_HTTP OR TRITON_ENABLE_PERF_ANALYZER OR TRITON_ENABLE_EXAMPLE PRIVATE client-common-library ) -endif() + + add_library( + json_utils_static STATIC + $ + ) + + add_library( + TritonClient::json_utils_static ALIAS json_utils_static + ) + + foreach(_json_target json-utils-library json_utils_static) + target_compile_features(${_json_target} PRIVATE cxx_std_${TRITON_MIN_CXX_STANDARD}) + target_compile_options( + ${_json_target} PRIVATE + $<$,$,$>: + -Wall -Wextra -Wno-unused-parameter -Werror> + $<$:/W0 /D_WIN32_WINNT=0x0A00 /EHsc> + ) + + set_target_properties( + ${_json_target} + PROPERTIES + POSITION_INDEPENDENT_CODE ON + ) + + target_include_directories( + ${_json_target} + PUBLIC + $ + $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ) + + install( + FILES + ${CMAKE_CURRENT_SOURCE_DIR}/json_utils.h + DESTINATION include + ) + endforeach() + + install( + TARGETS + json_utils_static + EXPORT + triton-client-targets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + +endif() # TRITON_ENABLE_CC_HTTP OR TRITON_ENABLE_PERF_ANALYZER OR TRITON_ENABLE_EXAMPLES # # shm_utils @@ -75,6 +126,56 @@ target_link_libraries( client-common-library ) +add_library( + shm_utils_static STATIC + $ +) + +add_library( + TritonClient::shm_utils_static ALIAS shm_utils_static +) + +foreach(_shm_target shm-utils-library shm_utils_static) + target_compile_features(${_shm_target} PRIVATE cxx_std_${TRITON_MIN_CXX_STANDARD}) + target_compile_options( + ${_shm_target} PRIVATE + $<$,$,$>: + -Wall -Wextra -Wno-unused-parameter -Werror> + $<$:/W0 /D_WIN32_WINNT=0x0A00 /EHsc> + ) + + set_target_properties( + ${_shm_target} + PROPERTIES + POSITION_INDEPENDENT_CODE ON + ) + + target_include_directories( + ${_shm_target} + PUBLIC + $ + $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ) + + install( + FILES + ${CMAKE_CURRENT_SOURCE_DIR}/shm_utils.h + DESTINATION include + ) +endforeach() + +install( + TARGETS + shm_utils_static + EXPORT + triton-client-targets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) + if(TRITON_ENABLE_CC_GRPC OR TRITON_ENABLE_PERF_ANALYZER) # # libgrpcclient.so and libgrpcclient_static.a @@ -400,6 +501,7 @@ if(TRITON_ENABLE_CC_HTTP OR TRITON_ENABLE_CC_GRPC OR TRITON_ENABLE_PERF_ANALYZER FILES ${CMAKE_CURRENT_SOURCE_DIR}/common.h ${CMAKE_CURRENT_SOURCE_DIR}/ipc.h + ${CMAKE_CURRENT_SOURCE_DIR}/cencode.h DESTINATION include ) diff --git a/src/c++/perf_analyzer/genai-perf/tests/test_csv_exporter.py b/src/c++/perf_analyzer/genai-perf/tests/test_csv_exporter.py index e27ee9b2a..9a94ec439 100644 --- a/src/c++/perf_analyzer/genai-perf/tests/test_csv_exporter.py +++ b/src/c++/perf_analyzer/genai-perf/tests/test_csv_exporter.py @@ -27,7 +27,7 @@ import os from io import StringIO from pathlib import Path -from typing import Any, List +from typing import Any, List, Tuple import pytest from genai_perf import parser @@ -38,15 +38,13 @@ class TestCsvExporter: @pytest.fixture - def mock_read_write(self, monkeypatch: pytest.MonkeyPatch) -> List[tuple[str, str]]: + def mock_read_write(self, monkeypatch: pytest.MonkeyPatch) -> List[Tuple[str, str]]: """ This function will mock the open function for specific files. """ written_data = [] - original_open = open - def custom_open(filename, *args, **kwargs): def write(self: Any, content: str) -> int: print(f"Writing to {filename}") # To help with debugging failures diff --git a/src/c++/perf_analyzer/genai-perf/tests/test_json_exporter.py b/src/c++/perf_analyzer/genai-perf/tests/test_json_exporter.py index 686dc8da3..8b6e96e33 100644 --- a/src/c++/perf_analyzer/genai-perf/tests/test_json_exporter.py +++ b/src/c++/perf_analyzer/genai-perf/tests/test_json_exporter.py @@ -27,7 +27,7 @@ import json import os from io import StringIO -from typing import Any, List +from typing import Any, List, Tuple import genai_perf.parser as parser import pytest @@ -37,15 +37,13 @@ class TestJsonExporter: @pytest.fixture - def mock_read_write(self, monkeypatch: pytest.MonkeyPatch) -> List[tuple[str, str]]: + def mock_read_write(self, monkeypatch: pytest.MonkeyPatch) -> List[Tuple[str, str]]: """ This function will mock the open function for specific files. """ written_data = [] - original_open = open - def custom_open(filename, *args, **kwargs): def write(self: Any, content: str) -> int: print(f"Writing to {filename}") diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 3725789e0..ecc33b84d 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2021-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright 2021-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -38,6 +38,8 @@ option(TRITON_ENABLE_PERF_ANALYZER "Enable Performance Analyzer" OFF) option(TRITON_ENABLE_EXAMPLES "Include examples in build" OFF) option(TRITON_ENABLE_TESTS "Include tests in build" OFF) option(TRITON_ENABLE_GPU "Enable GPU support in libraries" OFF) +# Package Perf Analyzer with the Python Client -- Intended to be used by PA repo +option(TRITON_PACKAGE_PERF_ANALYZER "Include Perf Analyzer in pip wheel" OFF) set(TRITON_COMMON_REPO_TAG "main" CACHE STRING "Tag for triton-inference-server/common repo") diff --git a/src/python/library/CMakeLists.txt b/src/python/library/CMakeLists.txt index 87bfd4050..e552ec2f7 100644 --- a/src/python/library/CMakeLists.txt +++ b/src/python/library/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2020-2024, NVIDIA CORPORATION. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -100,7 +100,7 @@ if (NOT WIN32) ${WHEEL_DEPENDS} ) - if (${TRITON_ENABLE_PERF_ANALYZER}) + if (${TRITON_PACKAGE_PERF_ANALYZER}) set(perf_analyzer_arg --perf-analyzer ${CMAKE_INSTALL_PREFIX}/bin/perf_analyzer) endif() set(linux_wheel_stamp_file "linux_stamp.whl") diff --git a/src/python/library/setup.py b/src/python/library/setup.py index 58cddbecf..e31f5ddc0 100755 --- a/src/python/library/setup.py +++ b/src/python/library/setup.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright 2020-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright 2020-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -82,7 +82,7 @@ def req_file(filename, folder="requirements"): data_files = [ ("", ["LICENSE.txt"]), ] -if (PLATFORM_FLAG != "any") and ("@TRITON_ENABLE_PERF_ANALYZER@" == "ON"): +if (PLATFORM_FLAG != "any") and ("@TRITON_PACKAGE_PERF_ANALYZER@" == "ON"): data_files += [("bin", ["perf_analyzer", "perf_client"])] setup( From 06a601cb4caaf2af227875d8c68879a2c5ce226f Mon Sep 17 00:00:00 2001 From: David Yastremsky Date: Mon, 29 Jul 2024 16:39:43 -0700 Subject: [PATCH 3/3] Shorten filename parsing Run pre-commit hooks --- .../genai-perf/genai_perf/export_data/csv_exporter.py | 7 +++---- .../genai-perf/genai_perf/export_data/json_exporter.py | 9 +++++---- .../perf_analyzer/genai-perf/tests/test_csv_exporter.py | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/c++/perf_analyzer/genai-perf/genai_perf/export_data/csv_exporter.py b/src/c++/perf_analyzer/genai-perf/genai_perf/export_data/csv_exporter.py index 7633187ba..27a963034 100644 --- a/src/c++/perf_analyzer/genai-perf/genai_perf/export_data/csv_exporter.py +++ b/src/c++/perf_analyzer/genai-perf/genai_perf/export_data/csv_exporter.py @@ -63,10 +63,9 @@ def __init__(self, config: ExporterConfig): self._args = config.args def export(self) -> None: - filename = str(self._args.profile_export_file) - if filename.endswith(".json"): - filename = filename[:-5] - filename += "_genai_perf.csv" + filename = ( + self._output_dir / f"{self._args.profile_export_file.stem}_genai_perf.csv" + ) logger.info(f"Generating {filename}") with open(filename, mode="w", newline="") as f: diff --git a/src/c++/perf_analyzer/genai-perf/genai_perf/export_data/json_exporter.py b/src/c++/perf_analyzer/genai-perf/genai_perf/export_data/json_exporter.py index 2f61a7894..e1396b3a2 100644 --- a/src/c++/perf_analyzer/genai-perf/genai_perf/export_data/json_exporter.py +++ b/src/c++/perf_analyzer/genai-perf/genai_perf/export_data/json_exporter.py @@ -26,6 +26,7 @@ import json +import os from enum import Enum from typing import Dict @@ -50,10 +51,10 @@ def __init__(self, config: ExporterConfig): self._merge_stats_and_args() def export(self) -> None: - filename = str(self._args["profile_export_file"]) - if filename.endswith(".json"): - filename = filename[:-5] - filename += "_genai_perf.json" + prefix = os.path.splitext(os.path.basename(self._args["profile_export_file"]))[ + 0 + ] + filename = self._output_dir / f"{prefix}_genai_perf.json" logger.info(f"Generating {filename}") with open(str(filename), "w") as f: f.write(json.dumps(self._stats_and_args, indent=2)) diff --git a/src/c++/perf_analyzer/genai-perf/tests/test_csv_exporter.py b/src/c++/perf_analyzer/genai-perf/tests/test_csv_exporter.py index 9a94ec439..95bbfe254 100644 --- a/src/c++/perf_analyzer/genai-perf/tests/test_csv_exporter.py +++ b/src/c++/perf_analyzer/genai-perf/tests/test_csv_exporter.py @@ -133,7 +133,7 @@ def test_nonstreaming_llm_csv_output( """ artifacts_dir = "artifacts/model_name-openai-chat-concurrency1" custom_filename = "custom_export.json" - expected_filename = f"{artifacts_dir}/custom_export_genai_perf.csv" + expected_filename = f"custom_export_genai_perf.csv" argv = [ "genai-perf", "profile",