diff --git a/accuracy_tools/msprobe/csrc/utils/Constant.h b/accuracy_tools/msprobe/csrc/utils/Constant.h new file mode 100644 index 0000000000000000000000000000000000000000..2365ce198dee9423f3fe7b28e992109f37733ed7 --- /dev/null +++ b/accuracy_tools/msprobe/csrc/utils/Constant.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2025-2025. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CONST_H +#define CONST_H + +#include + +namespace Cst { + inline const size_t BUFFER_SIZE = 1024 * 1024; // 1MB + inline const uint8_t INDENT_WIDTH = 4; + inline const uint8_t ARGS_LEN_2 = 2; + inline const uint8_t ARGS_LEN_3 = 3; + inline const uint8_t ARGS_LEN_5 = 5; + + inline const char *LINK_LOG_LEVEL = "LINK_LOG_LEVEL"; + inline const char *LINK_DUMP_PATH = "LINK_DUMP_PATH"; + inline const char *LINK_STEP = "LINK_STEP"; + inline const char *LINK_RANK = "LINK_RANK"; + inline const char *LINK_SAVE_TENSOR_IDS = "LINK_SAVE_TENSOR_IDS"; + inline const char *LINK_SAVE_TENSOR_RUNNER = "LINK_SAVE_TENSOR_RUNNER"; + inline const char *LINK_SAVE_TILING = "LINK_SAVE_TILING"; + inline const char *LINK_SAVE_CPU_PROFILING = "LINK_SAVE_CPU_PROFILING"; + inline const char *LINK_SAVE_KERNEL_INFO = "LINK_SAVE_KERNEL_INFO"; + inline const char *LINK_SAVE_OP_INFO = "LINK_SAVE_OP_INFO"; + inline const char *LINK_SAVE_PARAM = "LINK_SAVE_PARAM"; + inline const char *LINK_DUMP_TASK = "LINK_DUMP_TASK"; + inline const char *LINK_SUMMARY_MODE = "LINK_SUMMARY_MODE"; + inline const char *LINK_BUFFER_SIZE = "LINK_BUFFER_SIZE"; + inline const char *LINK_DATA_MODE = "LINK_DATA_MODE"; + inline const char *LINK_DUMP_LEVEL = "LINK_DUMP_LEVEL"; + inline const char *LINK_STOP = "LINK_STOP"; + + const std::string SUBDIRNAME_DUMP_TENSOR = "dump_tensor_data"; + const std::string SUBDIRNAME_TILING = "dump_tiling_data"; + const std::string TASK_STAT = "statistics"; + const std::string TASK_TENSOR = "tensor"; + const std::string TASK_OVERFLOW = "overflow"; + const std::string INTENSOR = "intensor"; + const std::string OUTTENSOR = "outtensor"; + const std::string BEFORE = "before"; + const std::string AFTER = "after"; + const std::string MODE_INPUT = "input"; + const std::string MODE_OUTPUT = "output"; + const std::string MODE_ALL = "all"; + const std::string SUMMARY_MD5 = "md5"; + const std::string FRAMEWORK_MINDIELLM = "MindIE_LLM"; +} // namespace Cst + +#endif diff --git a/accuracy_tools/msprobe/csrc/utils/DataType.h b/accuracy_tools/msprobe/csrc/utils/DataType.h new file mode 100644 index 0000000000000000000000000000000000000000..e4ed4134531ed07433551c201acc8099c7281a69 --- /dev/null +++ b/accuracy_tools/msprobe/csrc/utils/DataType.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2025-2025. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATA_TYPE_H +#define DATA_TYPE_H + +#include +#include +#include + +namespace Types { + struct TensorInfo { + std::string format; + std::string dtype; + std::string dims; + const void *hostData; + uint64_t dataSize; + std::string filePath; + }; + + struct TensorStats { + std::string type; + std::string dtype; + std::vector shape; + double max; + double min; + double mean; + double norm; + std::string crc32; + }; + + struct DTypeInfo { + uint64_t elemSize; + std::string descrDtype; + std::string dtypeName; + }; + + struct PathInfo { + std::string inOut; + std::string nodeName; + std::string argsName; + }; + + struct ArgsDumpJsonInit { + uint32_t bufferSize; + std::string task; + std::string level; + std::string framework; + std::string outputDir; + }; +} // namespace Types + +#endif diff --git a/accuracy_tools/msprobe/csrc/utils/Exception.h b/accuracy_tools/msprobe/csrc/utils/Exception.h new file mode 100644 index 0000000000000000000000000000000000000000..4eb65006b6d6b055d2e3317162ad6e2726ab768f --- /dev/null +++ b/accuracy_tools/msprobe/csrc/utils/Exception.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2025-2025. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EXCEPTION_H +#define EXCEPTION_H + +#include + +namespace Utility { + class MsprobeException : public std::runtime_error { + public: + explicit MsprobeException(const std::string &msg) : std::runtime_error("msprobe [ERROR]: " + msg) { + } + }; +} // namespace Utility + +#endif diff --git a/accuracy_tools/msprobe/csrc/utils/IO.cpp b/accuracy_tools/msprobe/csrc/utils/IO.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4a109339e54833e2826469a8305217581f779c4f --- /dev/null +++ b/accuracy_tools/msprobe/csrc/utils/IO.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2025-2025. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "utils/IO.h" + +#include +#include +#include + +#include "utils/Constant.h" +#include "utils/DataType.h" +#include "utils/Exception.h" +#include "utils/Log.h" +#include "utils/Path.h" +#include "utils/Str.h" + +namespace Utility { + static void PrintSaveFailMsg(const std::exception &e, const std::string &filePath, const uint64_t dataSize) { + LOG_ERROR << "Exception during write: " << e.what(); + bool tagSpaceFree = SafePath::IsDiskSpaceValid(filePath, dataSize); + LOG_ERROR << " Possible check 1: Disk space - 1 (sufficient), 0 (insufficient), current: " << tagSpaceFree; + } + + template + void SaveRawNpy(const std::vector &data, + const std::string &filePath, + const std::vector &shape, + const std::string &descrDtype) { + static_assert(std::is_trivially_copyable::value, "T must be trivially copyable"); + + std::ofstream out(filePath, std::ios::binary); + if (!out) { + throw MsprobeException("Cannot open file: " + filePath); + } + + std::string magic = "\x93NUMPY"; + uint8_t major = 1; + uint8_t minor = 0; + + std::ostringstream headerStream; + headerStream << "{'descr': '" << descrDtype << "', 'fortran_order': False, 'shape': ("; + for (size_t i = 0; i < shape.size(); ++i) { + headerStream << shape[i]; + if (i != shape.size() - 1) + headerStream << ", "; + } + if (shape.size() == 1) + headerStream << ","; + headerStream << "), }"; + + std::string header = headerStream.str(); + size_t padding = 16 - ((magic.size() + 2 + 2 + header.size()) % 16); + header.append(padding, ' '); + header += '\n'; + + out.write(magic.c_str(), magic.size()); + out.put(static_cast(major)); + out.put(static_cast(minor)); + + uint16_t hlen = static_cast(header.size()); + char buf[sizeof(hlen)]; + std::memcpy(buf, &hlen, sizeof(hlen)); + out.write(buf, sizeof(hlen)); + + out.write(header.c_str(), header.size()); + + try { + std::vector rawBytes(data.size() * sizeof(T)); + std::memcpy(rawBytes.data(), data.data(), rawBytes.size()); + out.write(rawBytes.data(), rawBytes.size()); + } catch (const std::exception &e) { + PrintSaveFailMsg(e, filePath, data.size() * sizeof(T)); + } + } + + static void SaveStringNpy(const std::vector &strings, + const std::string &filePath, + const std::vector &shape) { + if (strings.empty()) { + throw MsprobeException("Invalid or empty string array."); + } + size_t maxStrLen = 0; + for (const auto &s : strings) { + maxStrLen = std::max(maxStrLen, s.size()); + } + std::vector flatData(strings.size() * maxStrLen, '\0'); + for (size_t i = 0; i < strings.size(); ++i) { + std::memcpy(&flatData[i * maxStrLen], strings[i].c_str(), std::min(strings[i].size(), maxStrLen)); + } + std::string descrDtype = "|S" + std::to_string(maxStrLen); + SaveRawNpy(flatData, filePath, shape, descrDtype); + } + + void SaveJson(const ordered_json &data, const std::string &path, const std::ios_base::openmode &mode) { + SafePath checker(path, SafePath::PathType::FILE, SafePath::Mode::WRITE, 0, ".json"); + std::string validatedPath = checker.Check(false); + std::ofstream outfile(validatedPath, mode); + if (outfile.is_open()) { + outfile << data.dump(Cst::INDENT_WIDTH) << std::endl; + outfile.close(); + SafePath::ChangePermission(validatedPath, SafePath::PERM_640); + } else { + LOG_ERROR << "Unable to open file! File path: " << validatedPath; + } + } + + void SaveBytes(const uint8_t *data, + const fs::path &path, + const uint64_t &dataSize, + const std::ios_base::openmode &mode) { + SafePath checker(path, SafePath::PathType::FILE, SafePath::Mode::WRITE, 0, ".bin"); + std::string validatedPath = checker.Check(false); + std::ofstream outfile(validatedPath, mode); + if (outfile.is_open()) { + try { + outfile.write(static_cast(static_cast(data)), dataSize); + outfile.close(); + SafePath::ChangePermission(validatedPath, SafePath::PERM_640); + } catch (const std::exception &e) { + PrintSaveFailMsg(e, validatedPath, dataSize); + } + } else { + LOG_ERROR << "Unable to open file. File path: " << validatedPath; + } + } + + const std::unordered_map dtypeMap = { + {"0", {sizeof(float), " &shape, + const void *data, + const uint64_t &dataSize, + const std::string &path) { + SafePath checker(path, SafePath::PathType::FILE, SafePath::Mode::WRITE, 0, ".npy"); + std::string validatedPath = checker.Check(false); + + if (dtypeKey != "13") { + auto it = dtypeMap.find(dtypeKey); + if (it != dtypeMap.end()) { + const Types::DTypeInfo &info = it->second; + const auto *bytePtr = static_cast(data); + std::vector byteVec(bytePtr, bytePtr + dataSize); + SaveRawNpy(byteVec, validatedPath, shape, info.descrDtype); + } else { + LOG_ERROR << "Unsupported dtype: " << dtypeKey; + } + } else { + auto stringVecPtr = static_cast *>(data); + SaveStringNpy(*stringVecPtr, validatedPath, shape); + } + } + + void SaveTxt(const std::string &data, const std::string &path, const std::ios_base::openmode &mode) { + SafePath checker(path, SafePath::PathType::FILE, SafePath::Mode::WRITE, 0, ".txt"); + std::string validatedPath = checker.Check(false); + std::ofstream outfile(validatedPath, mode); + if (outfile.is_open()) { + outfile << data << std::endl; + outfile.close(); + SafePath::ChangePermission(validatedPath, SafePath::PERM_640); + } else { + LOG_ERROR << "Unable to open file. File path: " << validatedPath; + } + } +} // namespace Utility diff --git a/accuracy_tools/msprobe/csrc/utils/IO.h b/accuracy_tools/msprobe/csrc/utils/IO.h new file mode 100644 index 0000000000000000000000000000000000000000..01ea29f6069def1a975e274b0022399035349b56 --- /dev/null +++ b/accuracy_tools/msprobe/csrc/utils/IO.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2025-2025. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IO_H +#define IO_H + +#include + +#include "nlohmann/json.hpp" + +#include "utils/DataType.h" +#include "utils/Path.h" + +namespace Utility { + using json = nlohmann::json; + using ordered_json = nlohmann::ordered_json; + + extern const std::unordered_map dtypeMap; + + void SaveJson(const ordered_json &data, const std::string &path, const std::ios_base::openmode &mode); + void + SaveBytes(const uint8_t *data, const fs::path &path, const uint64_t &dataSize, const std::ios_base::openmode &mode); + void SaveNpy(const std::string &dtypeKey, + const std::vector &shape, + const void *data, + const uint64_t &dataSize, + const std::string &path); + void SaveTxt(const std::string &data, const std::string &path, const std::ios_base::openmode &mode); +} // namespace Utility + +#endif