Add functions that tell what capabilities are supported
The new functions added in this commit allow a caller to tell up
front what functions, function variants and monitors are
supported.
Also,
* fixed a few documentation/formatting issues
* fixed a process_info test issue
Change-Id: I2184ab1a4a6898f847e791f273e2185d556e78e9
[ROCm/rocm_smi_lib commit: 551b15182b]
Цей коміт міститься в:
Бінарний файл не відображається.
@@ -114,6 +114,9 @@ typedef enum {
|
||||
//!< execution of function
|
||||
RSMI_STATUS_UNEXPECTED_SIZE, //!< An unexpected amount of data
|
||||
//!< was read
|
||||
RSMI_STATUS_NO_DATA, //!< No data was found for a given
|
||||
//!< input
|
||||
|
||||
RSMI_STATUS_UNKNOWN_ERROR = 0xFFFFFFFF, //!< An unknown error occurred
|
||||
} rsmi_status_t;
|
||||
|
||||
@@ -667,6 +670,43 @@ typedef struct {
|
||||
uint32_t pasid; //!< PASID
|
||||
} rsmi_process_info_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Opaque handle to function-support object
|
||||
*/
|
||||
typedef struct rsmi_func_id_iter_handle * rsmi_func_id_iter_handle_t;
|
||||
|
||||
//! Place-holder "variant" for functions that have don't have any variants,
|
||||
//! but do have monitors or sensors.
|
||||
#define RSMI_DEFAULT_VARIANT 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
/**
|
||||
* @brief This union holds the value of an ::rsmi_func_id_iter_handle_t. The
|
||||
* value may be a function name, or an ennumerated variant value of types
|
||||
* such as ::rsmi_memory_type_t, ::rsmi_temperature_metric_t, etc.
|
||||
*/
|
||||
typedef union id {
|
||||
uint64_t id; //!< uint64_t representation of value
|
||||
const char *name; //!< name string (applicable to functions only)
|
||||
union {
|
||||
//!< Used for ::rsmi_memory_type_t variants
|
||||
rsmi_memory_type_t memory_type;
|
||||
//!< Used for ::rsmi_temperature_metric_t variants
|
||||
rsmi_temperature_metric_t temp_metric;
|
||||
//!< Used for ::rsmi_event_type_t variants
|
||||
rsmi_event_type_t evnt_type;
|
||||
//!< Used for ::rsmi_event_group_t variants
|
||||
rsmi_event_group_t evnt_group;
|
||||
//!< Used for ::rsmi_clk_type_t variants
|
||||
rsmi_clk_type_t clk_type;
|
||||
//!< Used for ::rsmi_fw_block_t variants
|
||||
rsmi_fw_block_t fw_block;
|
||||
//!< Used for ::rsmi_gpu_block_t variants
|
||||
rsmi_gpu_block_t gpu_block_type;
|
||||
};
|
||||
} rsmi_func_id_value_t;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/** @defgroup InitShutAdmin Initialization and Shutdown
|
||||
* These functions are used for initialization of ROCm SMI and clean up when
|
||||
@@ -811,10 +851,10 @@ rsmi_status_t rsmi_dev_brand_get(uint32_t dv_ind, char *brand, uint32_t len);
|
||||
/**
|
||||
* @brief Get the name string for a give vendor ID
|
||||
*
|
||||
* @details Given vendor ID @p id, a pointer to a caller provided char buffer
|
||||
* @p name, and a length of this buffer @p len, this function will write the
|
||||
* name of the vendor (up to @p len characters) buffer @p name. The @p id may
|
||||
* be a device vendor or subsystem vendor ID.
|
||||
* @details Given a device index @p dv_ind, a pointer to a caller provided
|
||||
* char buffer @p name, and a length of this buffer @p len, this function will
|
||||
* write the name of the vendor (up to @p len characters) buffer @p name. The
|
||||
* @p id may be a device vendor or subsystem vendor ID.
|
||||
*
|
||||
* If the integer ID associated with the vendor is not found in one of the
|
||||
* system files containing device name information (e.g.
|
||||
@@ -822,7 +862,7 @@ rsmi_status_t rsmi_dev_brand_get(uint32_t dv_ind, char *brand, uint32_t len);
|
||||
* as a string. Updating the system name files can be accompplished with
|
||||
* "sudo update-pciids".
|
||||
*
|
||||
* @param[in] id a vendor ID
|
||||
* @param[in] dv_ind a device index
|
||||
*
|
||||
* @param[inout] name a pointer to a caller provided char buffer to which the
|
||||
* name will be written
|
||||
@@ -835,7 +875,8 @@ rsmi_status_t rsmi_dev_brand_get(uint32_t dv_ind, char *brand, uint32_t len);
|
||||
* be written.
|
||||
*
|
||||
*/
|
||||
rsmi_status_t rsmi_dev_vendor_name_get(uint32_t id, char *name, size_t len);
|
||||
rsmi_status_t rsmi_dev_vendor_name_get(uint32_t dv_ind, char *name,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* @brief Get the serial number string for a device
|
||||
@@ -1202,16 +1243,14 @@ rsmi_dev_power_cap_set(uint32_t dv_ind, uint32_t sensor_ind, uint64_t cap);
|
||||
/**
|
||||
* @brief Set the power profile
|
||||
*
|
||||
* @details Given a device index @p dv_ind, a sensor index sensor_ind, and a
|
||||
* @p profile, this function will attempt to set the current profile to the
|
||||
* provided profile. The provided profile must be one of the currently
|
||||
* supported profiles, as indicated by a call to
|
||||
* ::rsmi_dev_power_profile_presets_get()
|
||||
* @details Given a device index @p dv_ind and a @p profile, this function will
|
||||
* attempt to set the current profile to the provided profile. The provided
|
||||
* profile must be one of the currently supported profiles, as indicated by a
|
||||
* call to ::rsmi_dev_power_profile_presets_get()
|
||||
*
|
||||
* @param[in] dv_ind a device index
|
||||
*
|
||||
* @param[in] sensor_ind a 0-based sensor index. Normally, this will be 0.
|
||||
* If a device has more than one sensor, it could be greater than 0.
|
||||
* @param[in] reserved Not currently used. Set to 0.
|
||||
*
|
||||
* @param[in] profile a ::rsmi_power_profile_preset_masks_t that hold the mask
|
||||
* of the desired new power profile
|
||||
@@ -1220,7 +1259,7 @@ rsmi_dev_power_cap_set(uint32_t dv_ind, uint32_t sensor_ind, uint64_t cap);
|
||||
*
|
||||
*/
|
||||
rsmi_status_t
|
||||
rsmi_dev_power_profile_set(uint32_t dv_ind, uint32_t sensor_ind,
|
||||
rsmi_dev_power_profile_set(uint32_t dv_ind, uint32_t reserved,
|
||||
rsmi_power_profile_preset_masks_t profile);
|
||||
/** @} */ // end of PowerCont
|
||||
/*****************************************************************************/
|
||||
@@ -1728,25 +1767,6 @@ rsmi_status_t rsmi_dev_overdrive_level_set(int32_t dv_ind, uint32_t od);
|
||||
rsmi_status_t rsmi_dev_gpu_clk_freq_set(uint32_t dv_ind,
|
||||
rsmi_clk_type_t clk_type, uint64_t freq_bitmask);
|
||||
|
||||
/**
|
||||
* @brief Set the frequency limits for the specified clock
|
||||
*
|
||||
* @details Given a device index @p dv_ind, a clock type (::rsmi_clk_type_t)
|
||||
* @p clk, and a pointer to a ::rsmi_range_t @p range containing the desired
|
||||
* upper and lower frequency limits, this function will attempt to set the
|
||||
* frequency limits to those specified in @p range.
|
||||
*
|
||||
* @param[in] dv_ind a device index
|
||||
*
|
||||
* @param[in] clk The clock type for which the limits should be imposed.
|
||||
*
|
||||
* @param[in] range A pointer to the ::rsmi_range_t containing the desired limits
|
||||
*
|
||||
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.
|
||||
*/
|
||||
rsmi_status_t rsmi_dev_od_freq_range_set(uint32_t dv_ind, rsmi_clk_type_t clk,
|
||||
rsmi_range_t *range);
|
||||
|
||||
/** @} */ // end of PerfCont
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -1958,7 +1978,7 @@ rsmi_status_string(rsmi_status_t status, const char **status_string);
|
||||
* ::RSMI_STATUS_SUCCESS if the device associatee with @p dv_ind
|
||||
* support counting events of the type indicated by @p group.
|
||||
*
|
||||
* ::RSMI_STATUS_NOT_SUPPORTED If the device does not support event group @p
|
||||
* ::RSMI_STATUS_NOT_FOUND If the device does not support event group @p
|
||||
* group
|
||||
*
|
||||
*/
|
||||
@@ -2125,6 +2145,7 @@ rsmi_compute_process_info_get(rsmi_process_info_t *procs, uint32_t *num_items);
|
||||
rsmi_status_t
|
||||
rsmi_compute_process_info_by_pid_get(uint32_t pid, rsmi_process_info_t *proc);
|
||||
|
||||
|
||||
/** @} */ // end of SysInfo
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -2169,6 +2190,225 @@ rsmi_dev_xgmi_error_reset(uint32_t dv_ind);
|
||||
|
||||
/** @} */ // end of SysInfo
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/** @defgroup APISupport Supported Functions
|
||||
* API function support varies by both GPU type and the version of the
|
||||
* installed ROCm stack. The functions described in this section can be used
|
||||
* to determine, up front, which functions are supported for a given device
|
||||
* on a system. If such "up front" knowledge of support for a function is not
|
||||
* needed, alternatively, one can call a device related function and check the
|
||||
* return code.
|
||||
*
|
||||
* Some functions have several variations ("variants") where some variants are
|
||||
* supported and others are not. For example, on a given device,
|
||||
* ::rsmi_dev_temp_metric_get may support some types of temperature metrics
|
||||
* (e.g., ::RSMI_TEMP_CRITICAL_HYST), but not others
|
||||
* (e.g., ::RSMI_TEMP_EMERGENCY).
|
||||
*
|
||||
* In addition to a top level of variant support for a function, a function
|
||||
* may have varying support for monitors/sensors. These are considered
|
||||
* "sub-variants" in functions described in this section. Continuing the
|
||||
* ::rsmi_dev_temp_metric_get example, if variant
|
||||
* ::RSMI_TEMP_CRITICAL_HYST is supported, perhaps
|
||||
* only the sub-variant sensors ::RSMI_TEMP_TYPE_EDGE
|
||||
* and ::RSMI_TEMP_TYPE_EDGE are supported, but not
|
||||
* ::RSMI_TEMP_TYPE_MEMORY.
|
||||
*
|
||||
* In cases where a function takes in a sensor id parameter but does not have
|
||||
* any "top level" variants, the functions in this section will indicate a
|
||||
* default "variant", ::RSMI_DEFAULT_VARIANT, for the top level variant, and
|
||||
* the various monitor support will be sub-variants of this.
|
||||
*
|
||||
* The functions in this section use the "iterator" concept to list which
|
||||
* functions are supported; to list which variants of the supported functions
|
||||
* are supported; and finally which monitors/sensors are supported for a
|
||||
* variant.
|
||||
*
|
||||
* Here is example code that prints out all supported functions, their
|
||||
* supported variants and sub-variants. Please see the related descriptions
|
||||
* functions and RSMI types.
|
||||
* \latexonly
|
||||
* \pagebreak
|
||||
* \endlatexonly
|
||||
* \code{.cpp}
|
||||
* rsmi_func_id_iter_handle_t iter_handle, var_iter, sub_var_iter;
|
||||
* rsmi_func_id_value_t value;
|
||||
* rsmi_status_t err;
|
||||
*
|
||||
* for (uint32_t i = 0; i < <number of devices>; ++i) {
|
||||
* std::cout << "Supported RSMI Functions:" << std::endl;
|
||||
* std::cout << "\tVariants (Monitors)" << std::endl;
|
||||
*
|
||||
* err = rsmi_dev_supported_func_iterator_open(i, &iter_handle);
|
||||
*
|
||||
* while (1) {
|
||||
* err = rsmi_func_iter_value_get(iter_handle, &value);
|
||||
* std::cout << "Function Name: " << value.name << std::endl;
|
||||
*
|
||||
* err = rsmi_dev_supported_variant_iterator_open(iter_handle, &var_iter);
|
||||
* if (err != RSMI_STATUS_NO_DATA) {
|
||||
* std::cout << "\tVariants/Monitors: ";
|
||||
* while (1) {
|
||||
* err = rsmi_func_iter_value_get(var_iter, &value);
|
||||
* if (value.id == RSMI_DEFAULT_VARIANT) {
|
||||
* std::cout << "Default Variant ";
|
||||
* } else {
|
||||
* std::cout << value.id;
|
||||
* }
|
||||
* std::cout << " (";
|
||||
*
|
||||
* err =
|
||||
* rsmi_dev_supported_variant_iterator_open(var_iter, &sub_var_iter);
|
||||
* if (err != RSMI_STATUS_NO_DATA) {
|
||||
*
|
||||
* while (1) {
|
||||
* err = rsmi_func_iter_value_get(sub_var_iter, &value);
|
||||
* std::cout << value.id << ", ";
|
||||
*
|
||||
* err = rsmi_func_iter_next(sub_var_iter);
|
||||
*
|
||||
* if (err == RSMI_STATUS_NO_DATA) {
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
* err = rsmi_dev_supported_func_iterator_close(&sub_var_iter);
|
||||
* }
|
||||
*
|
||||
* std::cout << "), ";
|
||||
*
|
||||
* err = rsmi_func_iter_next(var_iter);
|
||||
*
|
||||
* if (err == RSMI_STATUS_NO_DATA) {
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
* std::cout << std::endl;
|
||||
*
|
||||
* err = rsmi_dev_supported_func_iterator_close(&var_iter);
|
||||
* }
|
||||
*
|
||||
* err = rsmi_func_iter_next(iter_handle);
|
||||
*
|
||||
* if (err == RSMI_STATUS_NO_DATA) {
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
* err = rsmi_dev_supported_func_iterator_close(&iter_handle);
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get a function name iterator of supported RSMI functions for a device
|
||||
*
|
||||
* @details Given a device index @p dv_ind, this function will write a function
|
||||
* iterator handle to the caller-provided memory pointed to by @p handle. This
|
||||
* handle can be used to iterate through all the supported functions.
|
||||
*
|
||||
* @param[in] dv_ind a device index of device for which support information is
|
||||
* requested
|
||||
*
|
||||
* @param[inout] handle A pointer to caller-provided memory to which the
|
||||
* function iterator will be written.
|
||||
*
|
||||
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.
|
||||
*
|
||||
*/
|
||||
rsmi_status_t
|
||||
rsmi_dev_supported_func_iterator_open(uint32_t dv_ind,
|
||||
rsmi_func_id_iter_handle_t *handle);
|
||||
|
||||
/**
|
||||
* @brief Get a variant iterator for a given handle
|
||||
*
|
||||
* @details Given a ::rsmi_func_id_iter_handle_t @p obj_h, this function will
|
||||
* write a function iterator handle to the caller-provided memory pointed to
|
||||
* by @p var_iter. This handle can be used to iterate through all the supported
|
||||
* variants of the provided handle. @p obj_h may be a handle to a function
|
||||
* object, as provided by a call to ::rsmi_dev_supported_func_iterator_open, or
|
||||
* it may be a variant itself (from a call to
|
||||
* ::rsmi_dev_supported_variant_iterator_open), it which case @p var_iter will
|
||||
* be an iterator of the sub-variants of @p obj_h (e.g., monitors).
|
||||
*
|
||||
* This call allocates a small amount of memory to @p var_iter. To free this memory
|
||||
* ::rsmi_dev_supported_func_iterator_close should be called on the returned
|
||||
* iterator handle @p var_iter when it is no longer needed.
|
||||
*
|
||||
* @param[in] obj_h an iterator handle for which the variants are being requested
|
||||
*
|
||||
* @param[inout] var_iter A pointer to caller-provided memory to which the
|
||||
* sub-variant iterator will be written.
|
||||
*
|
||||
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.
|
||||
*
|
||||
*/
|
||||
rsmi_status_t
|
||||
rsmi_dev_supported_variant_iterator_open(rsmi_func_id_iter_handle_t obj_h,
|
||||
rsmi_func_id_iter_handle_t *var_iter);
|
||||
|
||||
/**
|
||||
* @brief Advance a function identifer iterator
|
||||
*
|
||||
* @details Given a function id iterator handle (::rsmi_func_id_iter_handle_t)
|
||||
* @p handle, this function will increment the iterator to point to the next
|
||||
* identifier. After a successful call to this function, obtaining the value
|
||||
* of the iterator @p handle will provide the value of the next item in the
|
||||
* list of functions/variants.
|
||||
*
|
||||
* If there are no more items in the list, ::RSMI_STATUS_NO_DATA is returned.
|
||||
*
|
||||
* @param[in] handle A pointer to an iterator handle to be incremented
|
||||
*
|
||||
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.
|
||||
* @retval ::RSMI_STATUS_NO_DATA is returned when list of identifiers has been
|
||||
* exhausted
|
||||
*
|
||||
*/
|
||||
rsmi_status_t
|
||||
rsmi_func_iter_next(rsmi_func_id_iter_handle_t handle);
|
||||
|
||||
/**
|
||||
* @brief Close a variant iterator handle
|
||||
*
|
||||
* @details Given a pointer to an ::rsmi_func_id_iter_handle_t @p handle, this
|
||||
* function will free the resources being used by the handle
|
||||
*
|
||||
* @param[in] handle A pointer to an iterator handle to be closed
|
||||
*
|
||||
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.
|
||||
*
|
||||
*/
|
||||
rsmi_status_t
|
||||
rsmi_dev_supported_func_iterator_close(rsmi_func_id_iter_handle_t *handle);
|
||||
|
||||
/**
|
||||
* @brief Get the value associated with a function/variant iterator
|
||||
*
|
||||
* @details Given an ::rsmi_func_id_iter_handle_t @p handle, this function
|
||||
* will write the identifier of the function/variant to the user provided
|
||||
* memory pointed to by @p value.
|
||||
*
|
||||
* @p value may point to a function name, a variant id, or a monitor/sensor
|
||||
* index, depending on what kind of iterator @p handle is
|
||||
*
|
||||
* @param[in] handle An iterator for which the value is being requested
|
||||
*
|
||||
* @param[inout] value A pointer to an ::rsmi_func_id_value_t provided by the
|
||||
* caller to which this function will write the value assocaited with @p handle
|
||||
*
|
||||
* @retval ::RSMI_STATUS_SUCCESS is returned upon successful call.
|
||||
*
|
||||
*/
|
||||
rsmi_status_t
|
||||
rsmi_func_iter_value_get(rsmi_func_id_iter_handle_t handle,
|
||||
rsmi_func_id_value_t *value);
|
||||
|
||||
/** @} */ // end of APISupport
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
@@ -45,6 +45,11 @@
|
||||
#ifndef INCLUDE_ROCM_SMI_ROCM_SMI_COMMON_H_
|
||||
#define INCLUDE_ROCM_SMI_ROCM_SMI_COMMON_H_
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#define DBG_FILE_ERROR(FN, WR_STR) \
|
||||
if (env_->debug_output_bitfield & RSMI_DEBUG_SYSFS_FILE_PATHS) { \
|
||||
std::cout << "*****" << __FUNCTION__ << std::endl; \
|
||||
@@ -60,6 +65,12 @@
|
||||
// Add different debug filters here, as powers of 2; e.g, 1, 2, 4, 8, ...
|
||||
#define RSMI_DEBUG_SYSFS_FILE_PATHS 1
|
||||
|
||||
struct rsmi_func_id_iter_handle {
|
||||
uintptr_t func_id_iter;
|
||||
uintptr_t container_ptr;
|
||||
uint32_t id_type;
|
||||
};
|
||||
|
||||
struct RocmSMI_env_vars {
|
||||
// Bitfield that is AND'd with various RSMI_DEBUG_* bits to determine
|
||||
// which debugging information should be turned on. Env. variable
|
||||
@@ -82,4 +93,14 @@ struct RocmSMI_env_vars {
|
||||
const char *path_power_root_override;
|
||||
};
|
||||
|
||||
// Support information data structures
|
||||
typedef std::vector<uint64_t> SubVariant;
|
||||
typedef SubVariant::const_iterator SubVariantIt;
|
||||
|
||||
typedef std::map<uint64_t, std::shared_ptr<SubVariant>> VariantMap;
|
||||
typedef VariantMap::const_iterator VariantMapIt;
|
||||
|
||||
typedef std::map<std::string, std::shared_ptr<VariantMap>> SupportedFuncMap;
|
||||
typedef SupportedFuncMap::const_iterator SupportedFuncMapIt;
|
||||
|
||||
#endif // INCLUDE_ROCM_SMI_ROCM_SMI_COMMON_H_
|
||||
|
||||
@@ -155,6 +155,11 @@ enum DevInfoTypes {
|
||||
kDevMemPageBad,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
std::vector<const char *> mandatory_depends;
|
||||
std::vector<DevInfoTypes> variants;
|
||||
} dev_depends_t;
|
||||
|
||||
class Device {
|
||||
public:
|
||||
explicit Device(std::string path, RocmSMI_env_vars const *e);
|
||||
@@ -185,6 +190,9 @@ class Device {
|
||||
pthread_mutex_t *mutex(void) {return mutex_.ptr;}
|
||||
evt::dev_evt_grp_set_t* supported_event_groups(void) {
|
||||
return &supported_event_groups_;}
|
||||
SupportedFuncMap *supported_funcs(void) {return &supported_funcs_;}
|
||||
void fillSupportedFuncs(void);
|
||||
void DumpSupportedFunctions(void);
|
||||
|
||||
private:
|
||||
std::shared_ptr<Monitor> monitor_;
|
||||
@@ -205,6 +213,7 @@ class Device {
|
||||
std::unordered_set<rsmi_event_group_t,
|
||||
evt::RSMIEventGrpHashFunction> supported_event_groups_;
|
||||
std::map<std::string, uint64_t> kfdNodePropMap_;
|
||||
SupportedFuncMap supported_funcs_;
|
||||
};
|
||||
|
||||
} // namespace smi
|
||||
|
||||
@@ -94,6 +94,7 @@ class Monitor {
|
||||
int writeMonitor(MonitorTypes type, uint32_t sensor_ind, std::string val);
|
||||
uint32_t setSensorLabelMap(void);
|
||||
uint32_t getSensorIndex(rsmi_temperature_type_t type);
|
||||
void fillSupportedFuncs(SupportedFuncMap *supported_funcs);
|
||||
|
||||
private:
|
||||
std::string MakeMonitorPath(MonitorTypes type, int32_t sensor_id);
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "rocm_smi/rocm_smi_common.h" // Should go before rocm_smi.h
|
||||
#include "rocm_smi/rocm_smi.h"
|
||||
#include "rocm_smi/rocm_smi_main.h"
|
||||
#include "rocm_smi/rocm_smi_device.h"
|
||||
@@ -1976,13 +1977,12 @@ rsmi_dev_power_profile_presets_get(uint32_t dv_ind, uint32_t sensor_ind,
|
||||
}
|
||||
|
||||
rsmi_status_t
|
||||
rsmi_dev_power_profile_set(uint32_t dv_ind, uint32_t sensor_ind,
|
||||
rsmi_dev_power_profile_set(uint32_t dv_ind, uint32_t dummy,
|
||||
rsmi_power_profile_preset_masks_t profile) {
|
||||
TRY
|
||||
REQUIRE_ROOT_ACCESS
|
||||
|
||||
++sensor_ind; // power sysfs files have 1-based indices
|
||||
|
||||
(void)dummy;
|
||||
DEVICE_MUTEX
|
||||
rsmi_status_t ret = set_power_profile(dv_ind, profile);
|
||||
return ret;
|
||||
@@ -2498,7 +2498,7 @@ rsmi_compute_process_info_get(rsmi_process_info_t *procs,
|
||||
|
||||
uint32_t procs_found = 0;
|
||||
|
||||
int err = amd::smi:: GetProcessInfo(procs, *num_items, &procs_found);
|
||||
int err = amd::smi::GetProcessInfo(procs, *num_items, &procs_found);
|
||||
|
||||
if (err) {
|
||||
return errno_to_rsmi_status(err);
|
||||
@@ -2666,3 +2666,245 @@ rsmi_dev_xgmi_error_reset(uint32_t dv_ind) {
|
||||
|
||||
CATCH
|
||||
}
|
||||
|
||||
enum iterator_handle_type {
|
||||
FUNC_ITER = 0,
|
||||
VARIANT_ITER,
|
||||
SUBVARIANT_ITER,
|
||||
};
|
||||
|
||||
rsmi_status_t
|
||||
rsmi_dev_supported_func_iterator_open(uint32_t dv_ind,
|
||||
rsmi_func_id_iter_handle_t *handle) {
|
||||
TRY
|
||||
GET_DEV_FROM_INDX
|
||||
|
||||
if (handle == nullptr) {
|
||||
return RSMI_STATUS_INVALID_ARGS;
|
||||
}
|
||||
|
||||
dev->fillSupportedFuncs();
|
||||
|
||||
*handle = new rsmi_func_id_iter_handle;
|
||||
|
||||
if (*handle == nullptr) {
|
||||
return RSMI_STATUS_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
(*handle)->id_type = FUNC_ITER;
|
||||
|
||||
if (dev->supported_funcs()->begin() == dev->supported_funcs()->end()) {
|
||||
return RSMI_STATUS_NO_DATA;
|
||||
} else {
|
||||
SupportedFuncMapIt *supp_func_iter = new SupportedFuncMapIt;
|
||||
|
||||
if (supp_func_iter == nullptr) {
|
||||
return RSMI_STATUS_OUT_OF_RESOURCES;
|
||||
}
|
||||
*supp_func_iter = dev->supported_funcs()->begin();
|
||||
|
||||
(*handle)->func_id_iter = reinterpret_cast<uintptr_t>(supp_func_iter);
|
||||
(*handle)->container_ptr =
|
||||
reinterpret_cast<uintptr_t>(dev->supported_funcs());
|
||||
}
|
||||
|
||||
return RSMI_STATUS_SUCCESS;
|
||||
|
||||
CATCH
|
||||
}
|
||||
|
||||
rsmi_status_t
|
||||
rsmi_dev_supported_variant_iterator_open(
|
||||
rsmi_func_id_iter_handle_t parent_iter,
|
||||
rsmi_func_id_iter_handle_t *var_iter) {
|
||||
TRY
|
||||
|
||||
if (var_iter == nullptr || parent_iter->id_type == SUBVARIANT_ITER) {
|
||||
return RSMI_STATUS_INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (parent_iter->func_id_iter == 0) {
|
||||
return RSMI_STATUS_NO_DATA;
|
||||
}
|
||||
|
||||
*var_iter = new rsmi_func_id_iter_handle;
|
||||
|
||||
if (*var_iter == nullptr) {
|
||||
return RSMI_STATUS_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
VariantMapIt *variant_itr = nullptr;
|
||||
SubVariantIt *sub_var_itr = nullptr;
|
||||
SupportedFuncMapIt *func_iter;
|
||||
std::shared_ptr<VariantMap> var_map_container;
|
||||
std::shared_ptr<SubVariant> sub_var_map_container;
|
||||
|
||||
switch (parent_iter->id_type) {
|
||||
case FUNC_ITER:
|
||||
func_iter =
|
||||
reinterpret_cast<SupportedFuncMapIt *>(parent_iter->func_id_iter);
|
||||
var_map_container = (*func_iter)->second;
|
||||
|
||||
if (var_map_container == nullptr) {
|
||||
return RSMI_STATUS_NO_DATA;
|
||||
}
|
||||
|
||||
variant_itr = new VariantMapIt;
|
||||
*variant_itr = var_map_container->begin();
|
||||
(*var_iter)->func_id_iter = reinterpret_cast<uintptr_t>(variant_itr);
|
||||
(*var_iter)->container_ptr =
|
||||
reinterpret_cast<uintptr_t>(var_map_container.get());
|
||||
(*var_iter)->id_type = VARIANT_ITER;
|
||||
break;
|
||||
|
||||
case VARIANT_ITER:
|
||||
variant_itr =
|
||||
reinterpret_cast<VariantMapIt *>(parent_iter->func_id_iter);
|
||||
sub_var_map_container = (*variant_itr)->second;
|
||||
|
||||
if (sub_var_map_container == nullptr) {
|
||||
return RSMI_STATUS_NO_DATA;
|
||||
}
|
||||
|
||||
sub_var_itr = new SubVariantIt;
|
||||
*sub_var_itr = sub_var_map_container->begin();
|
||||
(*var_iter)->func_id_iter = reinterpret_cast<uintptr_t>(sub_var_itr);
|
||||
(*var_iter)->container_ptr =
|
||||
reinterpret_cast<uintptr_t>(sub_var_map_container.get());
|
||||
(*var_iter)->id_type = SUBVARIANT_ITER;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(!"Unexpected iterator type");
|
||||
return RSMI_STATUS_INVALID_ARGS;
|
||||
}
|
||||
return RSMI_STATUS_SUCCESS;
|
||||
|
||||
CATCH
|
||||
}
|
||||
|
||||
rsmi_status_t
|
||||
rsmi_dev_supported_func_iterator_close(rsmi_func_id_iter_handle_t *handle) {
|
||||
TRY
|
||||
|
||||
if (handle == nullptr) {
|
||||
return RSMI_STATUS_INVALID_ARGS;
|
||||
}
|
||||
|
||||
if ((*handle)->id_type == FUNC_ITER) {
|
||||
SupportedFuncMapIt *supp_func_iter =
|
||||
reinterpret_cast<SupportedFuncMapIt *>((*handle)->func_id_iter);
|
||||
delete supp_func_iter;
|
||||
} else if ((*handle)->id_type == VARIANT_ITER) {
|
||||
VariantMapIt *var_iter =
|
||||
reinterpret_cast<VariantMapIt *>((*handle)->func_id_iter);
|
||||
delete var_iter;
|
||||
} else if ((*handle)->id_type == SUBVARIANT_ITER) {
|
||||
SubVariant *subvar_iter =
|
||||
reinterpret_cast<SubVariant *>((*handle)->func_id_iter);
|
||||
delete subvar_iter;
|
||||
} else {
|
||||
return RSMI_STATUS_INVALID_ARGS;
|
||||
}
|
||||
|
||||
delete *handle;
|
||||
|
||||
*handle = nullptr;
|
||||
|
||||
return RSMI_STATUS_SUCCESS;
|
||||
|
||||
CATCH
|
||||
}
|
||||
|
||||
rsmi_status_t
|
||||
rsmi_func_iter_value_get(rsmi_func_id_iter_handle_t handle,
|
||||
rsmi_func_id_value_t *value) {
|
||||
TRY
|
||||
if (value == nullptr) {
|
||||
return RSMI_STATUS_INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (handle->func_id_iter == 0) {
|
||||
return RSMI_STATUS_NO_DATA;
|
||||
}
|
||||
|
||||
SupportedFuncMapIt *func_itr = nullptr;
|
||||
VariantMapIt *variant_itr = nullptr;
|
||||
SubVariantIt *sub_var_itr = nullptr;
|
||||
|
||||
switch (handle->id_type) {
|
||||
case FUNC_ITER:
|
||||
func_itr = reinterpret_cast<SupportedFuncMapIt *>(handle->func_id_iter);
|
||||
value->name = (*func_itr)->first.c_str();
|
||||
break;
|
||||
|
||||
case VARIANT_ITER:
|
||||
variant_itr = reinterpret_cast<VariantMapIt *>(handle->func_id_iter);
|
||||
value->id = (*variant_itr)->first;
|
||||
break;
|
||||
|
||||
case SUBVARIANT_ITER:
|
||||
sub_var_itr = reinterpret_cast<SubVariantIt *>(handle->func_id_iter);
|
||||
value->id = *(*sub_var_itr);
|
||||
break;
|
||||
|
||||
default:
|
||||
return RSMI_STATUS_INVALID_ARGS;
|
||||
}
|
||||
CATCH
|
||||
return RSMI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
rsmi_status_t
|
||||
rsmi_func_iter_next(rsmi_func_id_iter_handle_t handle) {
|
||||
TRY
|
||||
if (handle->func_id_iter == 0) {
|
||||
return RSMI_STATUS_NO_DATA;
|
||||
}
|
||||
|
||||
SupportedFuncMapIt *func_iter;
|
||||
VariantMapIt *var_iter;
|
||||
SubVariantIt *sub_var_iter;
|
||||
|
||||
switch (handle->id_type) {
|
||||
case FUNC_ITER:
|
||||
func_iter = reinterpret_cast<SupportedFuncMapIt *>(handle->func_id_iter);
|
||||
(*func_iter)++;
|
||||
|
||||
if (*func_iter ==
|
||||
reinterpret_cast<SupportedFuncMap *>(handle->container_ptr)->end()) {
|
||||
handle->func_id_iter = 0;
|
||||
return RSMI_STATUS_NO_DATA;
|
||||
}
|
||||
break;
|
||||
|
||||
case VARIANT_ITER:
|
||||
var_iter = reinterpret_cast<VariantMapIt *>(handle->func_id_iter);
|
||||
(*var_iter)++;
|
||||
if (*var_iter ==
|
||||
reinterpret_cast<VariantMap *>(handle->container_ptr)->end()) {
|
||||
handle->func_id_iter = 0;
|
||||
return RSMI_STATUS_NO_DATA;
|
||||
}
|
||||
break;
|
||||
|
||||
case SUBVARIANT_ITER:
|
||||
sub_var_iter = reinterpret_cast<SubVariantIt *>(handle->func_id_iter);
|
||||
(*sub_var_iter)++;
|
||||
if (*sub_var_iter ==
|
||||
reinterpret_cast<SubVariant *>(handle->container_ptr)->end()) {
|
||||
handle->func_id_iter = 0;
|
||||
return RSMI_STATUS_NO_DATA;
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return RSMI_STATUS_INVALID_ARGS;
|
||||
}
|
||||
|
||||
return RSMI_STATUS_SUCCESS;
|
||||
|
||||
CATCH
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "rocm_smi/rocm_smi_main.h"
|
||||
#include "rocm_smi/rocm_smi_device.h"
|
||||
@@ -70,7 +71,7 @@ extern "C" {
|
||||
namespace amd {
|
||||
namespace smi {
|
||||
|
||||
// Sysfs file names
|
||||
// Device sysfs file names
|
||||
static const char *kDevPerfLevelFName = "power_dpm_force_performance_level";
|
||||
static const char *kDevDevIDFName = "device";
|
||||
static const char *kDevVendorIDFName = "vendor";
|
||||
@@ -82,7 +83,7 @@ static const char *kDevGPUMClkFName = "pp_dpm_mclk";
|
||||
static const char *kDevDCEFClkFName = "pp_dpm_dcefclk";
|
||||
static const char *kDevFClkFName = "pp_dpm_fclk";
|
||||
static const char *kDevSOCClkFName = "pp_dpm_socclk";
|
||||
static const char *kDevGPUPCIEClkFname = "pp_dpm_pcie";
|
||||
static const char *kDevPCIEClkFName = "pp_dpm_pcie";
|
||||
static const char *kDevPowerProfileModeFName = "pp_power_profile_mode";
|
||||
static const char *kDevPowerODVoltageFName = "pp_od_clk_voltage";
|
||||
static const char *kDevUsageFName = "gpu_busy_percent";
|
||||
@@ -106,17 +107,6 @@ static const char *kDevMemBusyPercentFName = "mem_busy_percent";
|
||||
static const char *kDevXGMIErrorFName = "xgmi_error";
|
||||
static const char *kDevSerialNumberFName = "serial_number";
|
||||
|
||||
// Strings that are found within sysfs files
|
||||
static const char *kDevPerfLevelAutoStr = "auto";
|
||||
static const char *kDevPerfLevelLowStr = "low";
|
||||
static const char *kDevPerfLevelHighStr = "high";
|
||||
static const char *kDevPerfLevelManualStr = "manual";
|
||||
static const char *kDevPerfLevelStandardStr = "profile_standard";
|
||||
static const char *kDevPerfLevelMinMClkStr = "profile_min_mclk";
|
||||
static const char *kDevPerfLevelMinSClkStr = "profile_min_sclk";
|
||||
static const char *kDevPerfLevelPeakStr = "profile_peak";
|
||||
static const char *kDevPerfLevelUnknownStr = "unknown";
|
||||
|
||||
// Firmware version files
|
||||
static const char *kDevFwVersionAsdFName = "fw_version/asd_fw_version";
|
||||
static const char *kDevFwVersionCeFName = "fw_version/ce_fw_version";
|
||||
@@ -205,6 +195,18 @@ static const std::map<DevKFDNodePropTypes, const char *> kDevKFDPropNameMap = {
|
||||
{kDevKFDNodePropMaxEngClkCComp, kDevKFDNodePropMaxEngClkCCompSName},
|
||||
{kDevKFDNodePropDomain, kDevKFDNodePropDomainSName},
|
||||
};
|
||||
|
||||
// Strings that are found within sysfs files
|
||||
static const char *kDevPerfLevelAutoStr = "auto";
|
||||
static const char *kDevPerfLevelLowStr = "low";
|
||||
static const char *kDevPerfLevelHighStr = "high";
|
||||
static const char *kDevPerfLevelManualStr = "manual";
|
||||
static const char *kDevPerfLevelStandardStr = "profile_standard";
|
||||
static const char *kDevPerfLevelMinMClkStr = "profile_min_mclk";
|
||||
static const char *kDevPerfLevelMinSClkStr = "profile_min_sclk";
|
||||
static const char *kDevPerfLevelPeakStr = "profile_peak";
|
||||
static const char *kDevPerfLevelUnknownStr = "unknown";
|
||||
|
||||
static const std::map<DevInfoTypes, const char *> kDevAttribNameMap = {
|
||||
{kDevPerfLevel, kDevPerfLevelFName},
|
||||
{kDevOverDriveLevel, kDevOverDriveLevelFName},
|
||||
@@ -217,7 +219,7 @@ static const std::map<DevInfoTypes, const char *> kDevAttribNameMap = {
|
||||
{kDevDCEFClk, kDevDCEFClkFName},
|
||||
{kDevFClk, kDevFClkFName},
|
||||
{kDevSOCClk, kDevSOCClkFName},
|
||||
{kDevPCIEClk, kDevGPUPCIEClkFname},
|
||||
{kDevPCIEClk, kDevPCIEClkFName},
|
||||
{kDevPowerProfileMode, kDevPowerProfileModeFName},
|
||||
{kDevUsage, kDevUsageFName},
|
||||
{kDevPowerODVoltage, kDevPowerODVoltageFName},
|
||||
@@ -276,6 +278,178 @@ static const std::map<rsmi_dev_perf_level, const char *> kDevPerfLvlMap = {
|
||||
{RSMI_DEV_PERF_LEVEL_UNKNOWN, kDevPerfLevelUnknownStr},
|
||||
};
|
||||
|
||||
static std::map<DevInfoTypes, uint8_t> kDevInfoVarTypeToRSMIVariant = {
|
||||
// rsmi_memory_type_t
|
||||
{kDevMemTotGTT, RSMI_MEM_TYPE_GTT},
|
||||
{kDevMemTotVisVRAM, RSMI_MEM_TYPE_VIS_VRAM},
|
||||
{kDevMemTotVRAM, RSMI_MEM_TYPE_VRAM},
|
||||
{kDevMemUsedGTT, RSMI_MEM_TYPE_GTT},
|
||||
{kDevMemUsedVisVRAM, RSMI_MEM_TYPE_VIS_VRAM},
|
||||
{kDevMemUsedVRAM, RSMI_MEM_TYPE_VRAM},
|
||||
|
||||
// rsmi_clk_type_t
|
||||
{kDevGPUSClk, RSMI_CLK_TYPE_SYS},
|
||||
{kDevGPUMClk, RSMI_CLK_TYPE_MEM},
|
||||
{kDevFClk, RSMI_CLK_TYPE_DF},
|
||||
{kDevDCEFClk, RSMI_CLK_TYPE_DCEF},
|
||||
{kDevSOCClk, RSMI_CLK_TYPE_SOC},
|
||||
|
||||
// rsmi_fw_block_t
|
||||
{kDevFwVersionAsd, RSMI_FW_BLOCK_ASD},
|
||||
{kDevFwVersionCe, RSMI_FW_BLOCK_CE},
|
||||
{kDevFwVersionDmcu, RSMI_FW_BLOCK_DMCU},
|
||||
{kDevFwVersionMc, RSMI_FW_BLOCK_MC},
|
||||
{kDevFwVersionMe, RSMI_FW_BLOCK_ME},
|
||||
{kDevFwVersionMec, RSMI_FW_BLOCK_MEC},
|
||||
{kDevFwVersionMec2, RSMI_FW_BLOCK_MEC2},
|
||||
{kDevFwVersionPfp, RSMI_FW_BLOCK_PFP},
|
||||
{kDevFwVersionRlc, RSMI_FW_BLOCK_RLC},
|
||||
{kDevFwVersionRlcSrlc, RSMI_FW_BLOCK_RLC_SRLC},
|
||||
{kDevFwVersionRlcSrlg, RSMI_FW_BLOCK_RLC_SRLG},
|
||||
{kDevFwVersionRlcSrls, RSMI_FW_BLOCK_RLC_SRLS},
|
||||
{kDevFwVersionSdma, RSMI_FW_BLOCK_SDMA},
|
||||
{kDevFwVersionSdma2, RSMI_FW_BLOCK_SDMA2},
|
||||
{kDevFwVersionSmc, RSMI_FW_BLOCK_SMC},
|
||||
{kDevFwVersionSos, RSMI_FW_BLOCK_SOS},
|
||||
{kDevFwVersionTaRas, RSMI_FW_BLOCK_TA_RAS},
|
||||
{kDevFwVersionTaXgmi, RSMI_FW_BLOCK_TA_XGMI},
|
||||
{kDevFwVersionUvd, RSMI_FW_BLOCK_UVD},
|
||||
{kDevFwVersionVce, RSMI_FW_BLOCK_VCE},
|
||||
{kDevFwVersionVcn, RSMI_FW_BLOCK_VCN},
|
||||
|
||||
// rsmi_gpu_block_t
|
||||
{kDevErrCntUMC, RSMI_GPU_BLOCK_UMC},
|
||||
{kDevErrCntSDMA, RSMI_GPU_BLOCK_SDMA},
|
||||
{kDevErrCntGFX, RSMI_GPU_BLOCK_GFX},
|
||||
|
||||
// rsmi_event_group_t
|
||||
{kDevDFCountersAvailable, RSMI_EVNT_GRP_XGMI}
|
||||
};
|
||||
|
||||
static const std::map<const char *, dev_depends_t> kDevFuncDependsMap = {
|
||||
// Functions with only mandatory dependencies
|
||||
{"rsmi_dev_id_get", {{kDevDevIDFName}, {}}},
|
||||
{"rsmi_dev_vendor_id_get", {{kDevVendorIDFName}, {}}},
|
||||
|
||||
{"rsmi_dev_name_get", {{kDevVendorIDFName,
|
||||
kDevDevIDFName}, {}}},
|
||||
{"rsmi_dev_brand_get", {{kDevVendorIDFName}, {}}},
|
||||
{"rsmi_dev_vendor_name_get", {{kDevVendorIDFName}, {}}},
|
||||
{"rsmi_dev_serial_number_get", {{kDevSerialNumberFName}, {}}},
|
||||
{"rsmi_dev_subsystem_id_get", {{kDevSubSysDevIDFName}, {}}},
|
||||
{"rsmi_dev_subsystem_name_get", {{kDevSubSysVendorIDFName,
|
||||
kDevVendorIDFName,
|
||||
kDevDevIDFName}, {}}},
|
||||
{"rsmi_dev_drm_render_minor_get", {{}, {}}},
|
||||
{"rsmi_dev_subsystem_vendor_id_get", {{kDevSubSysVendorIDFName}, {}}},
|
||||
{"rsmi_dev_unique_id_get", {{kDevUniqueIdFName}, {}}},
|
||||
{"rsmi_dev_pci_bandwidth_get", {{kDevPCIEClkFName}, {}}},
|
||||
{"rsmi_dev_pci_id_get", {{}, {}}},
|
||||
{"rsmi_dev_pci_throughput_get", {{kDevPCIEThruPutFName}, {}}},
|
||||
{"rsmi_dev_pci_replay_counter_get", {{kDevPCIEReplayCountFName}, {}}},
|
||||
{"rsmi_dev_pci_bandwidth_set", {{kDevPerfLevelFName,
|
||||
kDevPCIEClkFName}, {}}},
|
||||
{"rsmi_dev_power_profile_set", {{kDevPerfLevelFName,
|
||||
kDevPowerProfileModeFName}, {}}},
|
||||
{"rsmi_dev_memory_busy_percent_get", {{kDevMemBusyPercentFName}, {}}},
|
||||
{"rsmi_dev_busy_percent_get", {{kDevUsageFName}, {}}},
|
||||
{"rsmi_dev_memory_reserved_pages_get", {{kDevMemPageBadFName}, {}}},
|
||||
{"rsmi_dev_overdrive_level_get", {{kDevOverDriveLevelFName}, {}}},
|
||||
{"rsmi_dev_power_profile_presets_get", {{kDevPowerProfileModeFName}, {}}},
|
||||
{"rsmi_dev_perf_level_set", {{kDevPerfLevelFName}, {}}},
|
||||
{"rsmi_dev_perf_level_get", {{kDevPerfLevelFName}, {}}},
|
||||
{"rsmi_dev_overdrive_level_set", {{kDevOverDriveLevelFName}, {}}},
|
||||
{"rsmi_dev_vbios_version_get", {{kDevVBiosVerFName}, {}}},
|
||||
{"rsmi_dev_od_volt_info_get", {{kDevPowerODVoltageFName}, {}}},
|
||||
{"rsmi_dev_od_volt_curve_regions_get", {{kDevPowerODVoltageFName}, {}}},
|
||||
{"rsmi_dev_ecc_enabled_get", {{kDevErrCntFeaturesFName}, {}}},
|
||||
{"rsmi_dev_ecc_status_get", {{kDevErrCntFeaturesFName}, {}}},
|
||||
{"rsmi_dev_counter_group_supported", {{}, {}}},
|
||||
{"rsmi_dev_counter_create", {{}, {}}},
|
||||
{"rsmi_dev_xgmi_error_status", {{kDevXGMIErrorFName}, {}}},
|
||||
{"rsmi_dev_xgmi_error_reset", {{kDevXGMIErrorFName}, {}}},
|
||||
{"rsmi_dev_memory_reserved_pages_get", {{kDevMemPageBadFName}, {}}},
|
||||
|
||||
// These functions with variants, but no sensors/units. (May or may not
|
||||
// have mandatory dependencies.)
|
||||
{"rsmi_dev_memory_total_get", { .mandatory_depends = {},
|
||||
.variants = {
|
||||
kDevMemTotGTT, kDevMemTotVisVRAM,
|
||||
kDevMemTotVRAM,
|
||||
}
|
||||
}
|
||||
},
|
||||
{"rsmi_dev_memory_usage_get", { .mandatory_depends = {},
|
||||
.variants = {
|
||||
kDevMemUsedGTT,
|
||||
kDevMemUsedVisVRAM,
|
||||
kDevMemUsedVRAM,
|
||||
}
|
||||
}
|
||||
},
|
||||
{"rsmi_dev_gpu_clk_freq_get", { .mandatory_depends = {},
|
||||
.variants = {
|
||||
kDevGPUSClk,
|
||||
kDevGPUMClk,
|
||||
kDevFClk,
|
||||
kDevDCEFClk,
|
||||
kDevSOCClk,
|
||||
}
|
||||
}
|
||||
},
|
||||
{"rsmi_dev_gpu_clk_freq_set", { .mandatory_depends =
|
||||
{kDevPerfLevelFName},
|
||||
.variants = {
|
||||
kDevGPUSClk,
|
||||
kDevGPUMClk,
|
||||
kDevFClk,
|
||||
kDevDCEFClk,
|
||||
kDevSOCClk,
|
||||
}
|
||||
}
|
||||
},
|
||||
{"rsmi_dev_firmware_version_get", { .mandatory_depends = {},
|
||||
.variants = {
|
||||
kDevFwVersionAsd,
|
||||
kDevFwVersionCe,
|
||||
kDevFwVersionDmcu,
|
||||
kDevFwVersionMc,
|
||||
kDevFwVersionMe,
|
||||
kDevFwVersionMec,
|
||||
kDevFwVersionMec2,
|
||||
kDevFwVersionPfp,
|
||||
kDevFwVersionRlc,
|
||||
kDevFwVersionRlcSrlc,
|
||||
kDevFwVersionRlcSrlg,
|
||||
kDevFwVersionRlcSrls,
|
||||
kDevFwVersionSdma,
|
||||
kDevFwVersionSdma2,
|
||||
kDevFwVersionSmc,
|
||||
kDevFwVersionSos,
|
||||
kDevFwVersionTaRas,
|
||||
kDevFwVersionTaXgmi,
|
||||
kDevFwVersionUvd,
|
||||
kDevFwVersionVce,
|
||||
kDevFwVersionVcn,
|
||||
}
|
||||
}
|
||||
},
|
||||
{"rsmi_dev_ecc_count_get", { .mandatory_depends = {},
|
||||
.variants = {
|
||||
kDevErrCntUMC,
|
||||
kDevErrCntSDMA,
|
||||
kDevErrCntGFX,
|
||||
}
|
||||
}
|
||||
},
|
||||
{"rsmi_counter_available_counters_get", { .mandatory_depends = {},
|
||||
.variants = {
|
||||
kDevDFCountersAvailable,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
#define RET_IF_NONZERO(X) { \
|
||||
if (X) return X; \
|
||||
}
|
||||
@@ -632,6 +806,109 @@ int Device::getKFDNodeProperty(DevKFDNodePropTypes prop, uint64_t *val) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Device::DumpSupportedFunctions(void) {
|
||||
SupportedFuncMapIt func_iter = supported_funcs_.begin();
|
||||
|
||||
std::cout << "*** Supported Functions ***" << std::endl;
|
||||
|
||||
while (func_iter != supported_funcs_.end()) {
|
||||
std::cout << func_iter->first << std::endl;
|
||||
|
||||
std::cout << "\tSupported Variants(Monitors): ";
|
||||
if (func_iter->second) {
|
||||
VariantMapIt var_iter = func_iter->second->begin();
|
||||
|
||||
// We should have at least 1 supported variant or the function should
|
||||
// not be listed as supported.
|
||||
assert(var_iter != func_iter->second->end());
|
||||
|
||||
while (var_iter != func_iter->second->end()) {
|
||||
std::cout << static_cast<uint32_t>(var_iter->first);
|
||||
|
||||
if (var_iter->second) {
|
||||
std::cout << "(";
|
||||
|
||||
SubVariantIt mon_iter = var_iter->second->begin();
|
||||
|
||||
// We should have at least 1 supported monitor or the function should
|
||||
// not be listed as supported.
|
||||
assert(mon_iter != var_iter->second->end());
|
||||
while (mon_iter != var_iter->second->end()) {
|
||||
std::cout << static_cast<uint32_t>(*mon_iter) << ", ";
|
||||
mon_iter++;
|
||||
}
|
||||
std::cout << ")";
|
||||
}
|
||||
std::cout << ", ";
|
||||
var_iter++;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
} else {
|
||||
std::cout << "Not Applicable" << std::endl;
|
||||
}
|
||||
func_iter++;
|
||||
}
|
||||
}
|
||||
|
||||
void Device::fillSupportedFuncs(void) {
|
||||
if (supported_funcs_.size() != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::map<const char *, dev_depends_t>::const_iterator it =
|
||||
kDevFuncDependsMap.begin();
|
||||
std::string dev_rt = path_ + "/device";
|
||||
bool mand_depends_met;
|
||||
std::shared_ptr<VariantMap> supported_variants;
|
||||
|
||||
while (it != kDevFuncDependsMap.end()) {
|
||||
// First, see if all the mandatory dependencies are there
|
||||
std::vector<const char *>::const_iterator dep =
|
||||
it->second.mandatory_depends.begin();
|
||||
|
||||
mand_depends_met = true;
|
||||
for (; dep != it->second.mandatory_depends.end(); dep++) {
|
||||
std::string dep_path = dev_rt + "/" + *dep;
|
||||
if (!FileExists(dep_path.c_str())) {
|
||||
mand_depends_met = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mand_depends_met) {
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
// Then, see if the variants are supported.
|
||||
std::vector<DevInfoTypes>::const_iterator var =
|
||||
it->second.variants.begin();
|
||||
|
||||
if (it->second.variants.size() == 0) {
|
||||
supported_funcs_[it->first] = nullptr;
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
supported_variants = std::make_shared<VariantMap>();
|
||||
|
||||
for (; var != it->second.variants.end(); var++) {
|
||||
std::string variant_path = dev_rt + "/" + kDevAttribNameMap.at(*var);
|
||||
if (!FileExists(variant_path.c_str())) {
|
||||
continue;
|
||||
}
|
||||
// At this point we assume no monitors, so map to nullptr
|
||||
(*supported_variants)[kDevInfoVarTypeToRSMIVariant.at(*var)] = nullptr;
|
||||
}
|
||||
|
||||
if ((*supported_variants).size() > 0) {
|
||||
supported_funcs_[it->first] = supported_variants;
|
||||
}
|
||||
|
||||
it++;
|
||||
}
|
||||
monitor()->fillSupportedFuncs(&supported_funcs_);
|
||||
// DumpSupportedFunctions();
|
||||
}
|
||||
|
||||
#undef RET_IF_NONZERO
|
||||
} // namespace smi
|
||||
} // namespace amd
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
@@ -49,6 +50,8 @@
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <regex> // NOLINT
|
||||
#include <vector>
|
||||
|
||||
#include "rocm_smi/rocm_smi_main.h"
|
||||
#include "rocm_smi/rocm_smi_monitor.h"
|
||||
@@ -126,7 +129,100 @@ static const std::map<MonitorTypes, const char *> kMonitorNameMap = {
|
||||
{kMonTempLabel, kMonTempLabelName},
|
||||
};
|
||||
|
||||
Monitor::Monitor(std::string path, RocmSMI_env_vars const *e) :
|
||||
static std::map<MonitorTypes, uint64_t> kMonInfoVarTypeToRSMIVariant = {
|
||||
// rsmi_temperature_metric_t
|
||||
{kMonTemp, RSMI_TEMP_CURRENT},
|
||||
{kMonTempMax, RSMI_TEMP_MAX},
|
||||
{kMonTempMin, RSMI_TEMP_MIN},
|
||||
{kMonTempMaxHyst, RSMI_TEMP_MAX_HYST},
|
||||
{kMonTempMinHyst, RSMI_TEMP_MIN_HYST},
|
||||
{kMonTempCritical, RSMI_TEMP_CRITICAL},
|
||||
{kMonTempCriticalHyst, RSMI_TEMP_CRITICAL_HYST},
|
||||
{kMonTempEmergency, RSMI_TEMP_EMERGENCY},
|
||||
{kMonTempEmergencyHyst, RSMI_TEMP_EMERGENCY_HYST},
|
||||
{kMonTempCritMin, RSMI_TEMP_CRIT_MIN},
|
||||
{kMonTempCritMinHyst, RSMI_TEMP_CRIT_MIN_HYST},
|
||||
{kMonTempOffset, RSMI_TEMP_OFFSET},
|
||||
{kMonTempLowest, RSMI_TEMP_LOWEST},
|
||||
{kMonTempHighest, RSMI_TEMP_HIGHEST},
|
||||
{kMonInvalid, RSMI_DEFAULT_VARIANT},
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
std::vector<const char *> mandatory_depends;
|
||||
std::vector<MonitorTypes> variants;
|
||||
} monitor_depends_t;
|
||||
|
||||
static const std::map<const char *, monitor_depends_t> kMonFuncDependsMap = {
|
||||
{"rsmi_dev_power_ave_get", { .mandatory_depends = {kMonPowerAveName},
|
||||
.variants = {kMonInvalid},
|
||||
}
|
||||
},
|
||||
{"rsmi_dev_power_cap_get", { .mandatory_depends = {kMonPowerCapName},
|
||||
.variants = {kMonInvalid},
|
||||
}
|
||||
},
|
||||
{"rsmi_dev_power_cap_range_get", { .mandatory_depends =
|
||||
{kMonPowerCapMaxName,
|
||||
kMonPowerCapMinName},
|
||||
.variants = {kMonInvalid},
|
||||
}
|
||||
},
|
||||
{"rsmi_dev_power_cap_set", { .mandatory_depends =
|
||||
{kMonPowerCapMaxName,
|
||||
kMonPowerCapMinName,
|
||||
kMonPowerCapName},
|
||||
.variants = {kMonInvalid},
|
||||
}
|
||||
},
|
||||
|
||||
{"rsmi_dev_fan_rpms_get", { .mandatory_depends = {kMonFanRPMsName},
|
||||
.variants = {kMonInvalid},
|
||||
}
|
||||
},
|
||||
{"rsmi_dev_fan_speed_get", { .mandatory_depends = {kMonFanSpeedFName},
|
||||
.variants = {kMonInvalid},
|
||||
}
|
||||
},
|
||||
{"rsmi_dev_fan_speed_max_get", { .mandatory_depends =
|
||||
{kMonMaxFanSpeedFName},
|
||||
.variants = {kMonInvalid},
|
||||
}
|
||||
},
|
||||
{"rsmi_dev_temp_metric_get", { .mandatory_depends =
|
||||
{kMonTempLabelName},
|
||||
.variants = {kMonTemp,
|
||||
kMonTempMax,
|
||||
kMonTempMin,
|
||||
kMonTempMaxHyst,
|
||||
kMonTempMinHyst,
|
||||
kMonTempCritical,
|
||||
kMonTempCriticalHyst,
|
||||
kMonTempEmergency,
|
||||
kMonTempEmergencyHyst,
|
||||
kMonTempCritMin,
|
||||
kMonTempCritMinHyst,
|
||||
kMonTempOffset,
|
||||
kMonTempLowest,
|
||||
kMonTempHighest,
|
||||
},
|
||||
}
|
||||
},
|
||||
{"rsmi_dev_fan_reset", { .mandatory_depends =
|
||||
{kMonFanControlEnableName},
|
||||
.variants = {kMonInvalid},
|
||||
}
|
||||
},
|
||||
{"rsmi_dev_fan_speed_set", { .mandatory_depends =
|
||||
{kMonMaxFanSpeedFName,
|
||||
kMonFanControlEnableName,
|
||||
kMonFanSpeedFName},
|
||||
.variants = {kMonInvalid},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
Monitor::Monitor(std::string path, RocmSMI_env_vars const *e) :
|
||||
path_(path), env_(e) {
|
||||
}
|
||||
Monitor::~Monitor(void) {
|
||||
@@ -193,11 +289,149 @@ Monitor::setSensorLabelMap(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_supported_sensors(std::string dir_path, std::string fn_reg_ex,
|
||||
std::vector<uint64_t> *sensors) {
|
||||
auto hwmon_dir = opendir(dir_path.c_str());
|
||||
assert(hwmon_dir != nullptr);
|
||||
assert(sensors != nullptr);
|
||||
|
||||
sensors->clear();
|
||||
|
||||
std::string::size_type pos = fn_reg_ex.find('#');
|
||||
|
||||
if (pos == std::string::npos) {
|
||||
return -1;
|
||||
}
|
||||
fn_reg_ex.erase(pos, 1);
|
||||
fn_reg_ex.insert(pos, "([0-9]+)");
|
||||
fn_reg_ex = "\\b" + fn_reg_ex + "\\b";
|
||||
|
||||
auto dentry = readdir(hwmon_dir);
|
||||
std::smatch match;
|
||||
int64_t mon_val;
|
||||
|
||||
char *endptr;
|
||||
std::regex re(fn_reg_ex);
|
||||
std::string fn;
|
||||
|
||||
while (dentry != nullptr) {
|
||||
fn = dentry->d_name;
|
||||
if (std::regex_search(fn, match, re)) {
|
||||
assert(match.size() == 2); // 1 for whole match + 1 for sub-match
|
||||
errno = 0;
|
||||
mon_val = strtol(match.str(1).c_str(), &endptr, 10);
|
||||
assert(errno == 0);
|
||||
assert(*endptr == '\0');
|
||||
if (errno) {
|
||||
return -2;
|
||||
}
|
||||
sensors->push_back(mon_val);
|
||||
}
|
||||
dentry = readdir(hwmon_dir);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Monitor::getSensorIndex(rsmi_temperature_type_t type) {
|
||||
return temp_type_index_map_.at(type);
|
||||
}
|
||||
|
||||
static std::vector<uint64_t> get_intersection(std::vector<uint64_t> *v1,
|
||||
std::vector<uint64_t> *v2) {
|
||||
assert(v1 != nullptr);
|
||||
assert(v2 != nullptr);
|
||||
std::vector<uint64_t> intersect;
|
||||
|
||||
std::sort(v1->begin(), v1->end());
|
||||
std::sort(v2->begin(), v2->end());
|
||||
|
||||
std::set_intersection(v1->begin(), v1->end(), v2->begin(), v2->end(),
|
||||
std::back_inserter(intersect));
|
||||
return intersect;
|
||||
}
|
||||
|
||||
void Monitor::fillSupportedFuncs(SupportedFuncMap *supported_funcs) {
|
||||
std::map<const char *, monitor_depends_t>::const_iterator it =
|
||||
kMonFuncDependsMap.begin();
|
||||
std::string mon_root = path_;
|
||||
bool mand_depends_met;
|
||||
std::shared_ptr<VariantMap> supported_variants;
|
||||
std::vector<uint64_t> sensors_i;
|
||||
std::vector<uint64_t> intersect;
|
||||
int ret;
|
||||
|
||||
assert(supported_funcs != nullptr);
|
||||
|
||||
while (it != kMonFuncDependsMap.end()) {
|
||||
// First, see if all the mandatory dependencies are there
|
||||
std::vector<const char *>::const_iterator dep =
|
||||
it->second.mandatory_depends.begin();
|
||||
|
||||
mand_depends_met = true;
|
||||
|
||||
// Initialize "intersect". A monitor is considered supported if all of its
|
||||
// dependency monitors with the same sensor index are present. So we
|
||||
// initialize "intersect" with the set of sensors that exist for the first
|
||||
// mandatory monitor, and take intersection of that with the subsequent
|
||||
// dependency monitors. The main assumption here is that
|
||||
// variant_<sensor_i>'s sensor-based dependencies have the same index i;
|
||||
// in other words, variant_i is not dependent on a sensor j, j != i
|
||||
do {
|
||||
ret = get_supported_sensors(mon_root + "/", *dep, &intersect);
|
||||
if (ret == -1) {
|
||||
// In this case, the dependency is not sensor-specific, so just
|
||||
// see if the file exists.
|
||||
std::string dep_path = mon_root + "/" + *dep;
|
||||
if (!FileExists(dep_path.c_str())) {
|
||||
mand_depends_met = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dep++;
|
||||
} while (dep != it->second.mandatory_depends.end());
|
||||
|
||||
if (!mand_depends_met) {
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// "intersect" holds the set of sensors for the mandatory dependencies
|
||||
// that exist.
|
||||
|
||||
std::vector<MonitorTypes>::const_iterator var =
|
||||
it->second.variants.begin();
|
||||
supported_variants = std::make_shared<VariantMap>();
|
||||
|
||||
std::vector<uint64_t> supported_monitors;
|
||||
|
||||
for (; var != it->second.variants.end(); var++) {
|
||||
if (*var != kMonInvalid) {
|
||||
ret = get_supported_sensors(mon_root + "/",
|
||||
kMonitorNameMap.at(*var), &sensors_i);
|
||||
|
||||
if (ret == 0) {
|
||||
supported_monitors = get_intersection(&sensors_i, &intersect);
|
||||
}
|
||||
} else {
|
||||
supported_monitors = intersect;
|
||||
}
|
||||
if (supported_monitors.size() > 0) {
|
||||
(*supported_variants)[kMonInfoVarTypeToRSMIVariant.at(*var)] =
|
||||
std::make_shared<SubVariant>(supported_monitors);
|
||||
}
|
||||
}
|
||||
|
||||
if (it->second.variants.size() == 0) {
|
||||
(*supported_funcs)[it->first] = nullptr;
|
||||
supported_variants = nullptr; // Invoke destructor
|
||||
} else if ((*supported_variants).size() > 0) {
|
||||
(*supported_funcs)[it->first] = supported_variants;
|
||||
}
|
||||
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace smi
|
||||
} // namespace amd
|
||||
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* =============================================================================
|
||||
* ROC Runtime Conformance Release License
|
||||
* =============================================================================
|
||||
* The University of Illinois/NCSA
|
||||
* Open Source License (NCSA)
|
||||
*
|
||||
* Copyright (c) 2019, Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by:
|
||||
*
|
||||
* AMD Research and AMD ROC Software Development
|
||||
*
|
||||
* Advanced Micro Devices, Inc.
|
||||
*
|
||||
* www.amd.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal with the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimers.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimers in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
* - Neither the names of <Name of Development Group, Name of Institution>,
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this Software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS WITH THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "rocm_smi/rocm_smi.h"
|
||||
#include "rocm_smi_test/functional/api_support_read.h"
|
||||
#include "rocm_smi_test/test_common.h"
|
||||
#include "rocm_smi_test/test_utils.h"
|
||||
|
||||
TestAPISupportRead::TestAPISupportRead() : TestBase() {
|
||||
set_title("RSMI API Support Read Test");
|
||||
set_description("This test verifies that the supported APIs are corretly "
|
||||
"identified.");
|
||||
}
|
||||
|
||||
TestAPISupportRead::~TestAPISupportRead(void) {
|
||||
}
|
||||
|
||||
void TestAPISupportRead::SetUp(void) {
|
||||
TestBase::SetUp();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void TestAPISupportRead::DisplayTestInfo(void) {
|
||||
TestBase::DisplayTestInfo();
|
||||
}
|
||||
|
||||
void TestAPISupportRead::DisplayResults(void) const {
|
||||
TestBase::DisplayResults();
|
||||
return;
|
||||
}
|
||||
|
||||
void TestAPISupportRead::Close() {
|
||||
// This will close handles opened within rsmitst utility calls and call
|
||||
// rsmi_shut_down(), so it should be done after other hsa cleanup
|
||||
TestBase::Close();
|
||||
}
|
||||
|
||||
void TestAPISupportRead::Run(void) {
|
||||
rsmi_status_t err;
|
||||
|
||||
TestBase::Run();
|
||||
|
||||
rsmi_func_id_iter_handle_t iter_handle, var_iter, sub_var_iter;
|
||||
rsmi_func_id_value_t value;
|
||||
|
||||
for (uint32_t i = 0; i < num_monitor_devs(); ++i) {
|
||||
PrintDeviceHeader(i);
|
||||
|
||||
std::cout << "Supported RSMI Functions:" << std::endl;
|
||||
std::cout << "\tVariants (Monitors)" << std::endl;
|
||||
|
||||
err = rsmi_dev_supported_func_iterator_open(i, &iter_handle);
|
||||
CHK_ERR_ASRT(err)
|
||||
|
||||
while (1) {
|
||||
err = rsmi_func_iter_value_get(iter_handle, &value);
|
||||
CHK_ERR_ASRT(err)
|
||||
std::cout << "Function Name: " << value.name << std::endl;
|
||||
|
||||
err = rsmi_dev_supported_variant_iterator_open(iter_handle, &var_iter);
|
||||
if (err != RSMI_STATUS_NO_DATA) {
|
||||
CHK_ERR_ASRT(err)
|
||||
std::cout << "\tVariants/Monitors: ";
|
||||
while (1) {
|
||||
err = rsmi_func_iter_value_get(var_iter, &value);
|
||||
CHK_ERR_ASRT(err)
|
||||
if (value.id == RSMI_DEFAULT_VARIANT) {
|
||||
std::cout << "Default Variant ";
|
||||
} else {
|
||||
std::cout << value.id;
|
||||
}
|
||||
std::cout << " (";
|
||||
|
||||
err =
|
||||
rsmi_dev_supported_variant_iterator_open(var_iter, &sub_var_iter);
|
||||
if (err != RSMI_STATUS_NO_DATA) {
|
||||
CHK_ERR_ASRT(err)
|
||||
|
||||
while (1) {
|
||||
err = rsmi_func_iter_value_get(sub_var_iter, &value);
|
||||
CHK_ERR_ASRT(err)
|
||||
std::cout << value.id << ", ";
|
||||
|
||||
err = rsmi_func_iter_next(sub_var_iter);
|
||||
|
||||
if (err == RSMI_STATUS_NO_DATA) {
|
||||
break;
|
||||
}
|
||||
CHK_ERR_ASRT(err)
|
||||
}
|
||||
err = rsmi_dev_supported_func_iterator_close(&sub_var_iter);
|
||||
CHK_ERR_ASRT(err)
|
||||
}
|
||||
|
||||
std::cout << "), ";
|
||||
|
||||
err = rsmi_func_iter_next(var_iter);
|
||||
|
||||
if (err == RSMI_STATUS_NO_DATA) {
|
||||
break;
|
||||
}
|
||||
CHK_ERR_ASRT(err)
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
err = rsmi_dev_supported_func_iterator_close(&var_iter);
|
||||
CHK_ERR_ASRT(err)
|
||||
}
|
||||
|
||||
err = rsmi_func_iter_next(iter_handle);
|
||||
|
||||
if (err == RSMI_STATUS_NO_DATA) {
|
||||
break;
|
||||
}
|
||||
CHK_ERR_ASRT(err)
|
||||
|
||||
// err = rsmi_dev_supported_variant_iterator_open(iter_handle, &var_iter);
|
||||
//
|
||||
}
|
||||
err = rsmi_dev_supported_func_iterator_close(&iter_handle);
|
||||
CHK_ERR_ASRT(err)
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* =============================================================================
|
||||
* ROC Runtime Conformance Release License
|
||||
* =============================================================================
|
||||
* The University of Illinois/NCSA
|
||||
* Open Source License (NCSA)
|
||||
*
|
||||
* Copyright (c) 2019, Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by:
|
||||
*
|
||||
* AMD Research and AMD ROC Software Development
|
||||
*
|
||||
* Advanced Micro Devices, Inc.
|
||||
*
|
||||
* www.amd.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal with the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimers.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimers in
|
||||
* the documentation and/or other materials provided with the distribution.
|
||||
* - Neither the names of <Name of Development Group, Name of Institution>,
|
||||
* nor the names of its contributors may be used to endorse or promote
|
||||
* products derived from this Software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS WITH THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef TESTS_ROCM_SMI_TEST_FUNCTIONAL_API_SUPPORT_READ_H_
|
||||
#define TESTS_ROCM_SMI_TEST_FUNCTIONAL_API_SUPPORT_READ_H_
|
||||
|
||||
#include "rocm_smi_test/test_base.h"
|
||||
|
||||
class TestAPISupportRead : public TestBase {
|
||||
public:
|
||||
TestAPISupportRead();
|
||||
|
||||
// @Brief: Destructor for test case of TestAPISupportRead
|
||||
virtual ~TestAPISupportRead();
|
||||
|
||||
// @Brief: Setup the environment for measurement
|
||||
virtual void SetUp();
|
||||
|
||||
// @Brief: Core measurement execution
|
||||
virtual void Run();
|
||||
|
||||
// @Brief: Clean up and retrive the resource
|
||||
virtual void Close();
|
||||
|
||||
// @Brief: Display results
|
||||
virtual void DisplayResults() const;
|
||||
|
||||
// @Brief: Display information about what this test does
|
||||
virtual void DisplayTestInfo(void);
|
||||
};
|
||||
|
||||
#endif // TESTS_ROCM_SMI_TEST_FUNCTIONAL_API_SUPPORT_READ_H_
|
||||
@@ -120,7 +120,7 @@ void TestIdInfoRead::Run(void) {
|
||||
}
|
||||
}
|
||||
err = rsmi_dev_brand_get(i, buffer, kBufferLen);
|
||||
if(err != RSMI_STATUS_SUCCESS) {
|
||||
if (err != RSMI_STATUS_SUCCESS) {
|
||||
CHK_ERR_ASRT(err)
|
||||
} else {
|
||||
IF_VERB(STANDARD) {
|
||||
|
||||
@@ -118,8 +118,8 @@ TestPerfCntrReadWrite::testEventsIndividually(uint32_t dv_ind) {
|
||||
std::cout << "****************************" << std::endl;
|
||||
|
||||
for (PerfCntrEvtGrp grp : s_event_groups) {
|
||||
if (rsmi_dev_counter_group_supported(dv_ind, grp.group())
|
||||
== RSMI_STATUS_NOT_SUPPORTED) {
|
||||
ret = rsmi_dev_counter_group_supported(dv_ind, grp.group());
|
||||
if (ret == RSMI_STATUS_NOT_SUPPORTED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -202,12 +202,14 @@ TestPerfCntrReadWrite::testEventsSimultaneously(uint32_t dv_ind) {
|
||||
std::cout << "****************************" << std::endl;
|
||||
|
||||
for (PerfCntrEvtGrp grp : s_event_groups) {
|
||||
if (rsmi_dev_counter_group_supported(dv_ind, grp.group())
|
||||
== RSMI_STATUS_NOT_SUPPORTED) {
|
||||
std::cout << "\tEvent Group" << grp.name() <<
|
||||
|
||||
ret = rsmi_dev_counter_group_supported(dv_ind, grp.group());
|
||||
if (ret == RSMI_STATUS_NOT_SUPPORTED) {
|
||||
std::cout << "\tEvent Group " << grp.name() <<
|
||||
" is not supported. Skipping." << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
IF_VERB(STANDARD) {
|
||||
std::cout << "Testing Event Group " << grp.name() << std::endl;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ void TestProcInfoRead::Run(void) {
|
||||
|
||||
err = rsmi_compute_process_info_get(nullptr, &num_proc_found);
|
||||
if (err != RSMI_STATUS_SUCCESS) {
|
||||
if (err == RSMI_STATUS_FILE_ERROR) {
|
||||
if (err == RSMI_STATUS_NOT_SUPPORTED) {
|
||||
IF_VERB(STANDARD) {
|
||||
std::cout << "\t**Process info. read: Not supported on this machine"
|
||||
<< std::endl;
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
#include "functional/process_info_read.h"
|
||||
#include "functional/xgmi_read_write.h"
|
||||
#include "functional/mem_page_info_read.h"
|
||||
#include "functional/api_support_read.h"
|
||||
|
||||
static RSMITstGlobals *sRSMIGlvalues = nullptr;
|
||||
|
||||
@@ -218,6 +219,10 @@ TEST(rsmitstReadOnly, TestMemPageInfoRead) {
|
||||
TestMemPageInfoRead tst;
|
||||
RunGenericTest(&tst);
|
||||
}
|
||||
TEST(rsmitstReadOnly, TestAPISupportRead) {
|
||||
TestAPISupportRead tst;
|
||||
RunGenericTest(&tst);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
Посилання в новій задачі
Заблокувати користувача