numpy中的c源代码如何使用at符号(@)?

7

我一直在研究numpy的源代码,发现很多c源代码使用了@变量名称@这种结构。例如,在文件 "npy_math_complex.c.src" (位于这里):

/*==========================================================
* Constants
*=========================================================*/
static const @ctype@ c_1@c@ = {1.0@C@, 0.0};
static const @ctype@ c_half@c@ = {0.5@C@, 0.0};
static const @ctype@ c_i@c@ = {0.0, 1.0@C@};
static const @ctype@ c_ihalf@c@ = {0.0, 0.5@C@};
@ctype@@c@是什么意思?它们是一些宏吗?我猜它们不是普通的C宏,因为我查看了文件中列出的相关头文件,发现它们并没有使用“@”定义任何宏。 @name@distutils在将C代码编译成Python模块时使用的某种宏吗?
我以前从未见过C代码中使用@符号,所以有点困惑...

1
它被某种模板引擎用于生成多个非常相似的函数,其中@标记的部分被替换,但我从未弄清楚他们使用的模板系统或所生成代码的精确细节。 - user2357112
请注意,文件名 npy_math_complex.c.src 是一个提示... - ad absurdum
NumPy文档在此处提供了非常简要的概述:https://numpy.org/devdocs/reference/distutils_guide.html#other-files - Eric
1个回答

9
这是因为这些文件是模板。如果我没记错,NumPy使用了几个模板引擎(感谢@user2357112帮忙找到合适的引擎): 第二个引擎实际上负责将它们转换成“常规”的C文件-在编译之前。
基本上,这些函数会被克隆很多次,对于每个函数,特殊的占位符会插入在%之间。
例如,在这种情况下,它以此开头:
/**begin repeat
 * #type = npy_float, npy_double, npy_longdouble#
 * #ctype = npy_cfloat,npy_cdouble,npy_clongdouble#
 * #c = f, , l#
 * #C = F, , L#
 * ....
 */

因此,在第一次迭代中,@ctype@将被替换为npy_cfloat@c@将被替换为f@C@将被替换为F

static const npy_cfloat c_1f = {1.0F, 0.0};
static const npy_cfloat c_halff = {0.5F, 0.0};
static const npy_cfloat c_if = {0.0, 1.0F};
static const npy_cfloat c_ihalff = {0.0, 0.5F};

在下一次迭代中,@ctype@npy_cdouble,...
static const npy_cdouble c_1 = {1.0, 0.0};
static const npy_cdouble c_half = {0.5, 0.0};
static const npy_cdouble c_i = {0.0, 1.0};
static const npy_cdouble c_ihalf = {0.0, 0.5};

在第三次迭代中:

static const npy_clongdouble c_1l = {1.0L, 0.0};
static const npy_clongdouble c_halfl = {0.5L, 0.0};
static const npy_clongdouble c_il = {0.0, 1.0L};
static const npy_clongdouble c_ihalfl = {0.0, 0.5L};

这些文件随后被编译为普通的C文件。


1
我快速浏览了一下tempita用法的源码,但它似乎只用于生成Cython文件,而不是C。此外,其语法似乎与tempita不匹配。 C模板似乎采用了不同的处理方式。 - user2357112
@user2357112 哦,可能是这样。我找到了另一个明确提到 .xxx.src -> .xxx 转换的文档:https://github.com/numpy/numpy/blob/a5d71d64a0d2e7a50562df80349219080172f254/numpy/distutils/from_template.py 但很难确定那是否真的是在那里使用的。但有一件事我可以确定:他们使用了一个模板引擎:D - MSeifert
4
不,我认为那是另一个模板引擎。.c.src 文件似乎由同名的 numpy/distutils/conv_template.py 处理。 - user2357112
这个项目中的模板引擎比我预期的要多得多。 - user2357112
谢谢你指引我正确的方向!由于某种原因,我一直认为disutils正在进行替换...所以你为我节省了大量时间... - FormerPhysicist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接