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]
Цей коміт міститься в:
Chris Freehill
2019-09-03 17:41:08 -05:00
джерело 0bcdfe553d
коміт 8ea817f79e
14 змінених файлів з 1337 додано та 60 видалено
Бінарний файл не відображається.
+274 -34
Переглянути файл
@@ -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
+21
Переглянути файл
@@ -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_
+9
Переглянути файл
@@ -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
+1
Переглянути файл
@@ -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);
+246 -4
Переглянути файл
@@ -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
}
+291 -14
Переглянути файл
@@ -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
+235 -1
Переглянути файл
@@ -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_
+1 -1
Переглянути файл
@@ -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) {
+7 -5
Переглянути файл
@@ -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;
}
+1 -1
Переглянути файл
@@ -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;
+5
Переглянути файл
@@ -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);