* This file is part of the MindStudio project.
* Copyright (c) 2025 Huawei Technologies Co.,Ltd.
*
* MindStudio is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* ------------------------------------------------------------------------- */
#ifndef CATLASS_TUNER_MTVAR_H
#define CATLASS_TUNER_MTVAR_H
#include <mutex>
#include <vector>
#include <algorithm>
#include <random>
#include <functional>
namespace Catlass {
template<typename T>
class MTVar {
public:
using Type = T;
explicit MTVar() { var_ = T{}; }
explicit MTVar(T &t) : var_(t) {}
explicit MTVar(T &&t) : var_(std::move(t)) {}
MTVar(const MTVar &mtVar) = delete;
MTVar& operator=(const MTVar &mtVar) = delete;
inline const T Get()
{
std::lock_guard<decltype(mtx_)> lockGuard(mtx_);
return var_;
}
operator const T()
{
return Get();
}
const T operator=(const T &t)
{
Set(t);
return t;
}
inline void Set(const T &t)
{
std::lock_guard<decltype(mtx_)> lockGuard(mtx_);
var_ = t;
}
template<typename RetType>
RetType DoTransaction(const std::function<RetType(Type&)> &callee)
{
std::lock_guard<decltype(mtx_)> lockGuard(mtx_);
return callee(var_);
}
private:
T var_;
std::mutex mtx_;
};
template <class Element, class ElementRandom>
void FillRandomData(std::vector<Element>& data, ElementRandom low, ElementRandom high)
{
thread_local std::mt19937 engine(std::random_device{}());
if constexpr (std::is_integral_v<Element>) {
std::uniform_int_distribution<ElementRandom> dist(low, high);
std::generate(data.begin(), data.end(), [&]() {
return static_cast<Element>(dist(engine));
});
} else {
std::uniform_real_distribution<double> dist(low, high);
std::generate(data.begin(), data.end(), [&]() {
return static_cast<Element>(dist(engine));
});
}
}
template<typename T>
bool SafeMul(const std::vector<T>& numbers, uint64_t &product)
{
if (numbers.empty()) {
product = 0;
return true;
}
product = 1;
constexpr uint64_t max_uint64 = std::numeric_limits<uint64_t>::max();
for (T num : numbers) {
if (num == 0) {
product = 0;
return true;
}
if (product > max_uint64 / num) {
return false;
}
product *= num;
}
return true;
}
template<typename T>
inline void Erase(std::vector<T> &vec, typename std::vector<T>::size_type num)
{
if (num >= vec.size()) {
vec.clear();
return;
}
std::vector<T> tmp(vec.begin() + num, vec.end());
vec.swap(tmp);
}
}
#endif