m5/objects/__init__.py 文件 gem5 中发生了什么

What is happening in m5/objects/__init__.py file gem5

我是 gem5 模拟器的新手。我正在阅读文档 (http://www.m5sim.org/Configuration_/_Simulation_Scripts) 试图了解一切是如何实现的。当他们写到 Python 类 时,他们会这样说:

gem5 provides a collection of Python object classes that correspond to its C++ simulation object classes. These Python classes are defined in a Python module called "m5.objects". The Python class definitions for these objects can be found in .py files in src, typically in the same directory as their C++ definitions.

To make the Python classes visible, the configuration file must first import the class definitions from the m5 module

在m5/objects目录下只有一个文件“__init__.py”。这是代码:

from __future__ import print_function
from __future__ import absolute_import

from m5.internal import params
from m5.SimObject import *

try:
    modules = __loader__.modules
except NameError:
    modules = { }

for module in modules.keys():
    if module.startswith('m5.objects.'):
        exec("from %s import *" % module)

通常我不使用 Python 编程所以也许这就是问题所在,但我还没有完全理解这里发生了什么。在另一个 post Python's __loader__, what is it? 中,他们谈到了 loader 的意思,但我觉得我遗漏了一些东西。任何帮助,将不胜感激。提前致谢。

__loader__

考虑以下代码:

import sys
class FooImporter:
    def find_module(self, module_name, package_path):
        return self if module_name == 'foo' else None

    def load_module(self, module_name):
        print('FooImporter is working.')
        sys.modules[module_name] = __import__('sys')

# This activates the importer
sys.meta_path.append(FooImporter())
# This should trigger our importer to import 'foo'
import foo
# Show what we've just got
print(foo)

这将导致输出:

FooImporter is working.
<module 'sys' (built-in)>

只要您在 PYTHONPATH.

中没有名为 foo 的 python 模块

Python Import Hook (PEP 302) 允许我们自定义 import 的行为。在上面的示例中,模块 foo 被认为是由 FooImporter 找到和处理的。请注意,导入器将创建模块 foo 作为 sys 的别名。完整的导入器(与我们所见的简化导入器不同)将负责将导入模块的 __loader__ 属性设置为导入器本身。

Gem5 的导入挂钩

回到你的问题,gem5 通过其模块化设计使用相同的机制来加载 SimObject。您可以在 src/python/importer.py 以 class 名称 CodeImporter.

找到非常重要的进口商 class

导入模块 m5.object 时,比方说,

from m5.objects import Root

CodeImporter 将负责处理导入任务,其中将为导入的模块设置 __loader__ 属性(在本例中为 m5.objects)。如果您尝试在 m5/objects/__init__.py 中打印 __loader__,您将得到如下内容:

<importer.CodeImporter object at 0x7f4f58941d60>

__loader__.modules 是一个包含 gem5 维护的字典 SimObjects 其中每个项目将通过来自 src/sim/init.cc.

addModule() 调用添加

只要 SimObject 的 C++ 对应调用了 EmbeddedPython 的构造函数,它就会被添加到一个列表中,因此 gem5 初始化会记得将它添加到 [= 的实例中=25=]。例如,应该能够在注册 Root 对象的构建文件夹中找到 Root.py.cc 文件。 m5/object/__init__.py 末尾的循环只是通过这种机制导入已知 SimObject 的列表。

我认为这应该足以让某人了解潜在的魔法并(希望)解决他们的好奇心。