* 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.
* -------------------------------------------------------------------------
*/
#include "describerobject.h"
#include "describe_trace.h"
#include "cpython.h"
#include "utils.h"
namespace MemScope {
const size_t MAX_DESCRIBE_OWNER_LENGTH = 128;
static PyObject* PyMemScopeNewDescriber(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
if (type == nullptr || type->tp_alloc == nullptr) {
return nullptr;
}
static PyObject *self = nullptr;
if (self == nullptr) {
self = type->tp_alloc(type, 0);
}
Py_XINCREF(self);
return self;
}
PyDoc_STRVAR(DescribeDoc,
"describe($self, owner)\n--\n\nEnable debug.");
static PyObject* PyMemScopeDescribe(PyObject *self, PyObject *arg)
{
if (!PyUnicode_Check(arg)) {
PyErr_SetString(PyExc_TypeError, "Expected a string argument");
return nullptr;
}
std::string str = Utility::PythonObject(arg).Cast<std::string>();
if (str.size() > MAX_DESCRIBE_OWNER_LENGTH) {
PyErr_Format(PyExc_ValueError, "Input owner exceeds maximum allowed length %zu.", MAX_DESCRIBE_OWNER_LENGTH);
Py_RETURN_NONE;
}
DescribeTrace::GetInstance().AddDescribe(str);
Py_RETURN_NONE;
}
PyDoc_STRVAR(UnDescribeDoc,
"undescribe($self, owner)\n--\n\nEnable debug.");
static PyObject* PyMemScopeUnDescribe(PyObject *self, PyObject *arg)
{
if (!PyUnicode_Check(arg)) {
PyErr_SetString(PyExc_TypeError, "Expected a string argument");
return nullptr;
}
std::string str = Utility::PythonObject(arg).Cast<std::string>();
if (str.size() > MAX_DESCRIBE_OWNER_LENGTH) {
PyErr_Format(PyExc_ValueError, "Input owner exceeds maximum allowed length %zu.", MAX_DESCRIBE_OWNER_LENGTH);
Py_RETURN_NONE;
}
DescribeTrace::GetInstance().EraseDescribe(str);
Py_RETURN_NONE;
}
PyDoc_STRVAR(DescribeAddrDoc,
"describe_addr($self, addr, owner)\n--\n\nEnable debug.");
static PyObject* PyMemScopeDescribeAddr(PyObject *self, PyObject *args)
{
PyObject *addrObj = nullptr;
const char* str = nullptr;
if (!PyArg_ParseTuple(args, "Os", &addrObj, &str)) {
return nullptr;
}
if (std::strlen(str) > MAX_DESCRIBE_OWNER_LENGTH) {
PyErr_Format(PyExc_ValueError, "Input owner exceeds maximum allowed length %zu.", MAX_DESCRIBE_OWNER_LENGTH);
Py_RETURN_NONE;
}
uint64_t addr = static_cast<uint64_t>(PyLong_AsUnsignedLongLong(addrObj));
if (PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, "Parse tensor length failed!");
Py_RETURN_NONE;
}
DescribeTrace::GetInstance().DescribeAddr(addr, std::string(str));
Py_RETURN_NONE;
}
static PyMethodDef PyMemScopeDescriberMethods[] = {
{"describe_addr", reinterpret_cast<PyCFunction>(PyMemScopeDescribeAddr), METH_VARARGS, DescribeAddrDoc},
{"describe", reinterpret_cast<PyCFunction>(PyMemScopeDescribe), METH_O, DescribeDoc},
{"undescribe", reinterpret_cast<PyCFunction>(PyMemScopeUnDescribe), METH_O, UnDescribeDoc},
{nullptr, nullptr, 0, nullptr}
};
static PyTypeObject PyMemScopeDescriberType = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"_msmemscope._describer",
0,
0,
nullptr,
0,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
Py_TPFLAGS_DEFAULT,
nullptr,
nullptr,
nullptr,
nullptr,
0,
nullptr,
nullptr,
PyMemScopeDescriberMethods,
nullptr,
nullptr,
&PyBaseObject_Type,
nullptr,
nullptr,
nullptr,
0,
nullptr,
nullptr,
PyMemScopeNewDescriber,
PyObject_Del,
};
PyObject* PyMemScope_GetDescriber()
{
if (PyType_Ready(&PyMemScopeDescriberType) < 0) {
return nullptr;
}
return PyObject_New(PyObject, &PyMemScopeDescriberType);
}
}