diff --git a/projects/rocprofiler-compute/docs/install/core-install.rst b/projects/rocprofiler-compute/docs/install/core-install.rst index 36f3ebb41cf3..d3bf5a917d7e 100644 --- a/projects/rocprofiler-compute/docs/install/core-install.rst +++ b/projects/rocprofiler-compute/docs/install/core-install.rst @@ -104,6 +104,49 @@ This includes the ROCm profilers, dependencies, and base packages. This pip installation option installs only the components required to run ROCm profiling tools (ROCm Compute Profiler and :doc:`ROCm Systems Profiler `). It doesn't include other components for developing or building ROCm applications. To install the full development environment, use ``pip install "rocm[devel]"`` or refer to the appropriate pip installation instruction under :doc:`Install AMD ROCm ` for your system environment. + This environment runs profile mode. Analyze mode needs Python + packages that profile mode does not, so install those separately as + described in :ref:`analyze-deps`. + +.. _analyze-deps: + +Install the analyze mode dependencies +===================================== + +Profile mode uses only the standard library. Analyze mode needs packages such as +``numpy``, ``pandas``, ``dash``, and ``textual``, at the versions it pins. + +Install them into a virtual environment of their own, separate from the one your +profiled application uses. Those pins can conflict with a workload that brings +its own ``torch`` or ``numpy``, and a shared environment breaks either side. + +.. code-block:: bash + + python3 -m venv ~/.venvs/rocprof-compute-analyze + source ~/.venvs/rocprof-compute-analyze/bin/activate + python -m pip install --extra-index-url https://repo.amd.com/rocm/whl-multi-arch/ "rocm-profiler[compute-analyze]" + +This command uses ``--extra-index-url`` rather than the ``--index-url`` used +above because the analyze packages come from PyPI while ``rocm-profiler`` comes +from the AMD package repository. ``--index-url`` would replace PyPI and leave +the analyze packages unresolvable. + +To confirm the environment has everything analyze mode needs: + +.. code-block:: bash + + rocprof-compute analyze --verify-deps + +If you installed ROCm Compute Profiler from a package manager or the tarball +rather than pip, install the dependencies from the requirements file in that +installation: + +.. code-block:: bash + + pip install -r /libexec/rocprofiler-compute/requirements.txt + +```` is your ROCm installation path, for example ``/opt/rocm``. + Install from source =================== diff --git a/projects/rocprofiler-compute/docs/install/quickstart.rst b/projects/rocprofiler-compute/docs/install/quickstart.rst index 8e9d29d8d219..ab29f9ae927b 100644 --- a/projects/rocprofiler-compute/docs/install/quickstart.rst +++ b/projects/rocprofiler-compute/docs/install/quickstart.rst @@ -95,12 +95,15 @@ Ensure ROCm is installed and follow the steps: python3 -m venv ~/.venvs/rocprof-compute-analyze source ~/.venvs/rocprof-compute-analyze/bin/activate - pip install -r /libexec/rocprofiler-compute/requirements.txt + pip install --extra-index-url https://repo.amd.com/rocm/whl-multi-arch/ "rocm-profiler[compute-analyze]" - **Note:** Replace ```` with the ROCm installation path (e.g., ``/opt/rocm`` or ``/opt/rocm-7.3.0``). + To check that the environment has everything analyze mode needs, run + ``rocprof-compute analyze --verify-deps``. Profile your application with its own Python environment, then activate this - environment to run analyze mode on the results. + environment to run analyze mode on the results. For the packaged ROCm + installation and other ways to install these dependencies, see + :ref:`analyze-deps`. For detailed installation instructions, refer to :doc:`/install/core-install`. diff --git a/projects/rocprofiler-compute/src/argparser.py b/projects/rocprofiler-compute/src/argparser.py index f718f98d5f56..50768e52ca2f 100644 --- a/projects/rocprofiler-compute/src/argparser.py +++ b/projects/rocprofiler-compute/src/argparser.py @@ -674,6 +674,12 @@ def omniarg_parser( action="append", help="\t\tSpecify the raw data root dirs or desired results directory.", ) + analyze_group.add_argument( + "--verify-deps", + dest="verify_deps", + action="store_true", + help="\t\tCheck the Python dependencies analyze mode needs, then exit.", + ) analyze_group.add_argument( "--list-stats", action="store_true", diff --git a/projects/rocprofiler-compute/src/rocprof-compute b/projects/rocprofiler-compute/src/rocprof-compute index 54b98c4a6df9..0a927f238035 100755 --- a/projects/rocprofiler-compute/src/rocprof-compute +++ b/projects/rocprofiler-compute/src/rocprof-compute @@ -13,11 +13,17 @@ from pathlib import Path # Suppress pandas FutureWarning about chained assignment warnings.filterwarnings("ignore", category=FutureWarning) +_ANALYZE_DEPS_DOC = ( + "Install the analyze dependencies into their own virtual environment: " + "https://rocm.docs.amd.com/projects/rocprofiler-compute/en/latest/" + "install/core-install.html#analyze-deps" +) + try: from importlib import metadata from rocprof_compute_base import RocProfCompute - from utils.logger import console_error + from utils.logger import console_error, console_log except ImportError as e: print(f"{e}") # In wheel package, softlink is not supported. @@ -33,7 +39,7 @@ except ImportError as e: from importlib import metadata from rocprof_compute_base import RocProfCompute - from utils.logger import console_error + from utils.logger import console_error, console_log except ImportError: print( "\n[ERROR] Could not import rocprofiler-compute modules. " @@ -147,14 +153,22 @@ def verify_deps() -> None: if error: console_error( - "\nPlease verify all of the python dependencies called out " - "in the requirements file" - "\nare installed locally prior to running " - "rocprofiler-compute." - f"\n\nSee: {check_file}" + "\nAnalyze mode needs every dependency listed above before " + "it can run." + f"\n\n{_ANALYZE_DEPS_DOC}" ) return + searched = [ + str(Path(bindir).joinpath(location).resolve()) for location in deps_locations + ] + console_error( + "Cannot find requirements.txt at " + f"{', '.join(searched)}" + ", so the analyze dependencies could not be checked." + f"\n\n{_ANALYZE_DEPS_DOC}" + ) + def main() -> None: """Main function for rocprofiler-compute""" @@ -172,6 +186,9 @@ def main() -> None: # Analyze mode needs a higher Python floor and external dependencies check_analyze_python_version() verify_deps() + if rocprof_compute.get_args().verify_deps: + console_log("All analyze dependencies are installed.") + sys.exit(0) rocprof_compute.run_analysis() else: console_error("Unsupported execution mode") diff --git a/projects/rocprofiler-compute/src/rocprof_compute_base.py b/projects/rocprofiler-compute/src/rocprof_compute_base.py index 2df68b8d05f3..6680646dd7fd 100644 --- a/projects/rocprofiler-compute/src/rocprof_compute_base.py +++ b/projects/rocprofiler-compute/src/rocprof_compute_base.py @@ -115,6 +115,10 @@ def print_graphic(self) -> None: def get_mode(self) -> Optional[str]: return self.__mode + def get_args(self) -> argparse.Namespace: + assert self.__args is not None + return self.__args + def set_version(self) -> None: vData = get_version(config.rocprof_compute_home) self.__version["ver"] = vData["version"] diff --git a/projects/rocprofiler-compute/tests/unit/test_argparser.py b/projects/rocprofiler-compute/tests/unit/test_argparser.py index 9a92c5499acc..429e89f17843 100644 --- a/projects/rocprofiler-compute/tests/unit/test_argparser.py +++ b/projects/rocprofiler-compute/tests/unit/test_argparser.py @@ -144,6 +144,20 @@ def test_profile_kernel_iteration_range(): assert args.kernel_iteration_range == ["1", "3:5"] +# ============================================================================= +# analyze --verify-deps +# ============================================================================= + + +def test_analyze_verify_deps_defaults_off(): + assert build_args(["analyze", "-p", "/tmp/workload"]).verify_deps is False + + +def test_analyze_verify_deps_needs_no_workload(): + """The flag is a standalone environment check, so -p stays optional.""" + assert build_args(["analyze", "--verify-deps"]).verify_deps is True + + def test_pc_sampling_analyze_options(): """Defaults, overrides, and validation for the analyze PC sampling options.""" defaults = build_args(["analyze"])