当它在 Python 中显示“TypeError: not enough arguments for format string”时有什么建议吗?

问题描述

当我尝试通过 pycuda 运行矩阵乘法的示例时。

kernel_code_template = """
__global__ void MatrixMulKernel(float *a,float *b,float *c){
    int tx = threadIdx.x;
    int ty = threadIdx.y;
    float Pvalue = 0;
    for(int i=0; i<%(N)s; ++i){
        float Aelement = a[ty * %(N)s + i];
        float Belement = b[i * %(M)s + tx];
        Pvalue += Aelement * Belement;
    }
    c[ty * %[M]s + tx] = Pvalue;
}
"""

M,N = 2,3
kernel_code = kernel_code_template % {'M': M,'N': N}

它报告了如下错误

kernel_code = kernel_code_template % {'M': M,'N': N}
TypeError: not enough arguments for format string

我试图检查“%”标记是否有任何问题,但还没有得到任何结果。

解决方法

我认为您正在混合语法,%.format 字符串替换。在这里查看一个不错的摘要: https://pyformat.info/

现在我发现错误(第 11 行):%[M]s --> %(M)s

,

要直接回答问题,您需要将代码中的 %[M]s 更改为 %(M)s,如下所示:

kernel_code_template = """
__global__ void MatrixMulKernel(float *a,float *b,float *c){
    int tx = threadIdx.x;
    int ty = threadIdx.y;
    float Pvalue = 0;
    for(int i=0; i<%(N)s; ++i){
        float Aelement = a[ty * %(N)s + i];
        float Belement = b[i * %(M)s + tx];
        Pvalue += Aelement * Belement;
    }
    c[ty * %(M)s + tx] = Pvalue;
}
"""

然后它将按预期工作。但是,我强烈建议您开始使用 f 字符串,因为您表示您正在使用 Python 3.7:

kernel_code_template = f"""
__global__ void MatrixMulKernel(float *a,float *c){{
    int tx = threadIdx.x;
    int ty = threadIdx.y;
    float Pvalue = 0;
    for(int i=0; i<{N}; ++i){{
        float Aelement = a[ty * {N} + i];
        float Belement = b[i * {M} + tx];
        Pvalue += Aelement * Belement;
    }}
    c[ty * {M} + tx] = Pvalue;
}}
"""

不过,我知道有一些权衡,即 {{}} 转义。还有@Brandt 指出的 .format() 方法。选择最适合您的方式。