# Copyright 2020 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. # ============================================================================== """Prints ROCm library and header directories and versions found on the system. The script searches for ROCm library and header files on the system, inspects them to determine their version and prints the configuration to stdout. The path to inspect is specified through an environment variable (ROCM_PATH). If no valid configuration is found, the script prints to stderr and returns an error code. The script takes the directory specified by the ROCM_PATH environment variable. The script looks for headers and library files in a hard-coded set of subdirectories from base path of the specified directory. If ROCM_PATH is not specified, then "/opt/rocm" is used as it default value """ import io import os import re import sys class ConfigError(Exception): pass def _get_default_rocm_path(): return "/opt/rocm" def _get_rocm_install_path(): """Determines and returns the ROCm installation path.""" rocm_install_path = _get_default_rocm_path() if "ROCM_PATH" in os.environ: rocm_install_path = os.environ["ROCM_PATH"] # rocm_install_path = os.path.realpath(rocm_install_path) return rocm_install_path def _get_composite_version_number(major, minor, patch): return 10000 * major + 100 * minor + patch def _get_header_version(path, name): """Returns preprocessor defines in C header file.""" for line in io.open(path, "r", encoding="utf-8"): match = re.match(r"#define %s +(\d+)" % name, line) if match: value = match.group(1) return int(value) raise ConfigError('#define "{}" is either\n'.format(name) + " not present in file {} OR\n".format(path) + " its value is not an integer literal") def _find_rocm_config(rocm_install_path): def rocm_version_numbers_pre_rocm50(path, prior_err): version_file = os.path.join(path, ".info/version-dev") if not os.path.exists(version_file): raise ConfigError("{} ROCm version file ".format(prior_err) + '"{}" not found either.'.format(version_file)) version_numbers = [] with open(version_file) as f: version_string = f.read().strip() version_numbers = version_string.split(".") major = int(version_numbers[0]) minor = int(version_numbers[1]) patch = int(version_numbers[2].split("-")[0]) return major, minor, patch def rocm_version_numbers_post_rocm50(path): version_file = os.path.join(path, "include/rocm_version.h") if not os.path.exists(version_file): return False, 'ROCm version file "{}" not found.'.format(version_file) +\ " Trying an alternate approach to determine the ROCm version.", 0,0,0 major = _get_header_version(version_file, "ROCM_VERSION_MAJOR") minor = _get_header_version(version_file, "ROCM_VERSION_MINOR") patch = _get_header_version(version_file, "ROCM_VERSION_PATCH") return True, "", major, minor, patch status, error_msg, major, minor, patch = \ rocm_version_numbers_post_rocm50(rocm_install_path) if not status: major, minor, patch = \ rocm_version_numbers_pre_rocm50(rocm_install_path, error_msg) rocm_config = { "rocm_version_number": _get_composite_version_number(major, minor, patch) } return rocm_config def _find_hipruntime_config(rocm_install_path): def hipruntime_version_number(path): version_file = os.path.join(path, "hip/include/hip/hip_version.h") if not os.path.exists(version_file): raise ConfigError( 'HIP Runtime version file "{}" not found'.format(version_file)) # This header file has an explicit #define for HIP_VERSION, whose value # is (HIP_VERSION_MAJOR * 100 + HIP_VERSION_MINOR) # Retreive the major + minor and re-calculate here, since we do not # want get into the business of parsing arith exprs major = _get_header_version(version_file, "HIP_VERSION_MAJOR") minor = _get_header_version(version_file, "HIP_VERSION_MINOR") return 100 * major + minor hipruntime_config = { "hipruntime_version_number": hipruntime_version_number(rocm_install_path) } return hipruntime_config def _find_miopen_config(rocm_install_path): def miopen_version_numbers(path): version_file = os.path.join(path, "miopen/include/miopen/version.h") if not os.path.exists(version_file): raise ConfigError( 'MIOpen version file "{}" not found'.format(version_file)) major = _get_header_version(version_file, "MIOPEN_VERSION_MAJOR") minor = _get_header_version(version_file, "MIOPEN_VERSION_MINOR") patch = _get_header_version(version_file, "MIOPEN_VERSION_PATCH") return major, minor, patch major, minor, patch = miopen_version_numbers(rocm_install_path) miopen_config = { "miopen_version_number": _get_composite_version_number(major, minor, patch) } return miopen_config def _find_rocblas_config(rocm_install_path): def rocblas_version_numbers(path): possible_version_files = [ "rocblas/include/rocblas-version.h", # ROCm 3.7 and prior "rocblas/include/internal/rocblas-version.h", # ROCm 3.8 ] version_file = None for f in possible_version_files: version_file_path = os.path.join(path, f) if os.path.exists(version_file_path): version_file = version_file_path break if not version_file: raise ConfigError( "rocblas version file not found in {}".format( possible_version_files)) major = _get_header_version(version_file, "ROCBLAS_VERSION_MAJOR") minor = _get_header_version(version_file, "ROCBLAS_VERSION_MINOR") patch = _get_header_version(version_file, "ROCBLAS_VERSION_PATCH") return major, minor, patch major, minor, patch = rocblas_version_numbers(rocm_install_path) rocblas_config = { "rocblas_version_number": _get_composite_version_number(major, minor, patch) } return rocblas_config def _find_rocrand_config(rocm_install_path): def rocrand_version_number(path): possible_version_files = [ "rocrand/include/rocrand_version.h", # ROCm 5.0 and prior "include/rocrand/rocrand_version.h", # ROCm 5.1 ] version_file = None for f in possible_version_files: version_file_path = os.path.join(path, f) if os.path.exists(version_file_path): version_file = version_file_path break if not version_file: raise ConfigError( "rocrand version file not found in {}".format(possible_version_files)) version_number = _get_header_version(version_file, "ROCRAND_VERSION") return version_number rocrand_config = { "rocrand_version_number": rocrand_version_number(rocm_install_path) } return rocrand_config def _find_rocfft_config(rocm_install_path): def rocfft_version_numbers(path): version_file = os.path.join(path, "rocfft/include/rocfft-version.h") if not os.path.exists(version_file): raise ConfigError( 'rocfft version file "{}" not found'.format(version_file)) major = _get_header_version(version_file, "rocfft_version_major") minor = _get_header_version(version_file, "rocfft_version_minor") patch = _get_header_version(version_file, "rocfft_version_patch") return major, minor, patch major, minor, patch = rocfft_version_numbers(rocm_install_path) rocfft_config = { "rocfft_version_number": _get_composite_version_number(major, minor, patch) } return rocfft_config def _find_hipfft_config(rocm_install_path): def hipfft_version_numbers(path): version_file = os.path.join(path, "hipfft/include/hipfft-version.h") if not os.path.exists(version_file): raise ConfigError( 'hipfft version file "{}" not found'.format(version_file)) major = _get_header_version(version_file, "hipfftVersionMajor") minor = _get_header_version(version_file, "hipfftVersionMinor") patch = _get_header_version(version_file, "hipfftVersionPatch") return major, minor, patch major, minor, patch = hipfft_version_numbers(rocm_install_path) hipfft_config = { "hipfft_version_number": _get_composite_version_number(major, minor, patch) } return hipfft_config def _find_roctracer_config(rocm_install_path): def roctracer_version_numbers(path): version_file = os.path.join(path, "roctracer/include/roctracer.h") if not os.path.exists(version_file): raise ConfigError( 'roctracer version file "{}" not found'.format(version_file)) major = _get_header_version(version_file, "ROCTRACER_VERSION_MAJOR") minor = _get_header_version(version_file, "ROCTRACER_VERSION_MINOR") # roctracer header does not have a patch version number patch = 0 return major, minor, patch major, minor, patch = roctracer_version_numbers(rocm_install_path) roctracer_config = { "roctracer_version_number": _get_composite_version_number(major, minor, patch) } return roctracer_config def _find_hipsparse_config(rocm_install_path): def hipsparse_version_numbers(path): version_file = os.path.join(path, "hipsparse/include/hipsparse-version.h") if not os.path.exists(version_file): raise ConfigError( 'hipsparse version file "{}" not found'.format(version_file)) major = _get_header_version(version_file, "hipsparseVersionMajor") minor = _get_header_version(version_file, "hipsparseVersionMinor") patch = _get_header_version(version_file, "hipsparseVersionPatch") return major, minor, patch major, minor, patch = hipsparse_version_numbers(rocm_install_path) hipsparse_config = { "hipsparse_version_number": _get_composite_version_number(major, minor, patch) } return hipsparse_config def _find_hipsolver_config(rocm_install_path): def hipsolver_version_numbers(path): possible_version_files = [ "hipsolver/include/hipsolver-version.h", # ROCm 5.0 and prior "hipsolver/include/internal/hipsolver-version.h", # ROCm 5.1 ] version_file = None for f in possible_version_files: version_file_path = os.path.join(path, f) if os.path.exists(version_file_path): version_file = version_file_path break if not version_file: raise ConfigError("hipsolver version file not found in {}".format( possible_version_files)) major = _get_header_version(version_file, "hipsolverVersionMajor") minor = _get_header_version(version_file, "hipsolverVersionMinor") patch = _get_header_version(version_file, "hipsolverVersionPatch") return major, minor, patch major, minor, patch = hipsolver_version_numbers(rocm_install_path) hipsolver_config = { "hipsolver_version_number": _get_composite_version_number(major, minor, patch) } return hipsolver_config def _find_rocsolver_config(rocm_install_path): def rocsolver_version_numbers(path): version_file = os.path.join(path, "rocsolver/include/rocsolver-version.h") if not os.path.exists(version_file): raise ConfigError( 'rocsolver version file "{}" not found'.format(version_file)) major = _get_header_version(version_file, "ROCSOLVER_VERSION_MAJOR") minor = _get_header_version(version_file, "ROCSOLVER_VERSION_MINOR") patch = _get_header_version(version_file, "ROCSOLVER_VERSION_PATCH") return major, minor, patch major, minor, patch = rocsolver_version_numbers(rocm_install_path) rocsolver_config = { "rocsolver_version_number": _get_composite_version_number(major, minor, patch) } return rocsolver_config def find_rocm_config(): """Returns a dictionary of ROCm components config info.""" rocm_install_path = _get_rocm_install_path() if not os.path.exists(rocm_install_path): raise ConfigError( 'Specified ROCM_PATH "{}" does not exist'.format(rocm_install_path)) result = {} result["rocm_toolkit_path"] = rocm_install_path result.update(_find_rocm_config(rocm_install_path)) result.update(_find_hipruntime_config(rocm_install_path)) result.update(_find_miopen_config(rocm_install_path)) result.update(_find_rocblas_config(rocm_install_path)) result.update(_find_rocrand_config(rocm_install_path)) result.update(_find_rocfft_config(rocm_install_path)) if result["rocm_version_number"] >= 40100: result.update(_find_hipfft_config(rocm_install_path)) result.update(_find_roctracer_config(rocm_install_path)) result.update(_find_hipsparse_config(rocm_install_path)) if result["rocm_version_number"] >= 40500: result.update(_find_hipsolver_config(rocm_install_path)) result.update(_find_rocsolver_config(rocm_install_path)) return result def main(): try: for key, value in sorted(find_rocm_config().items()): print("%s: %s" % (key, value)) except ConfigError as e: sys.stderr.write("\nERROR: {}\n\n".format(str(e))) sys.exit(1) if __name__ == "__main__": main()