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

标签 python 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编程,所以也许这就是问题所在,但我还没有完全理解这里发生了什么。在另一篇文章中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 的导入钩子(Hook)

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

当模块 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,其中每个项目将通过来自 addModule() 调用添加src/sim/init.cc.

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

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

关于python - m5/objects/__init__.py 文件 gem5 中发生了什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63018861/

相关文章:

python - 如何从 API 使用 TensorFlow 部署和提供预测?

python - django-tables2 : Table subclassing and Meta inner class attributes

用于创建新 Excel 工作簿并填充单元格的 Python 函数

c++ - gem5 模拟 : error when goodbye. sayGoodbye(myName) 调用

python - 为什么字典有时是空的? (在 tornado.web.Application 类实例中保存数据)

python - 使用 h5py 将光栅图像添加到 HDF5 文件

scons - 构建gem5时出错: TypeError : File/hdd/Me/gem5/src/systemc/ext/systemc found where directory expected

c - 为什么一个简单的 C 程序需要系统调用?

computer-architecture - gem5 缓存统计 - 重置和转储

c++ - 如何在 Ruby 系统中运行 ARM 多线程程序