代码生成codegen

该模块提供了从SymPy表达式生成直接可编译代码的功能。该codegen功能是SymPy中代码生成功能的用户界面。下面为可能希望直接使用框架的高级用户提供了一些实现细节。

注意

该codegen调用是不是自动在sympy命名空间,必须首先执行才能使用

Run code block in SymPy Live

>>> from sympy.utilities.codegen import codegen

实现细则Implementation Details

介绍了内部结构中最重要的部分,因为高级用户可能希望直接使用。例如,通过为专用应用程序将代码生成器子类化。 优先使用上面记录的codegen()函数。

基本假设:

  • 常规数据结构描述了必须转换为C / Fortran /…代码的示例。此数据结构涵盖以一种或多种支持的语言提供的所有功能。
  • CodeGen类的扩展将多个Routine实例转换为可编译代码。每个派生的类都翻译成一种特定的语言。
  • 在许多情况下,人们想要一个简单的工作流程。最后一部分中的友函数是Routine / CodeGen之上的简单api。它们更易于使用,但功能不那么强大。

示例

Routine类是codegen模块的重要组成部分。Routine实例将codegen实用程序视为将数学表达式转换为编程语言中的一组语句的工具,负责提取和存储有关如何将数学封装在函数调用中的信息。因此,由Routine构造函数决定示例,将需要哪些参数以及是否应该有返回值。

API参考

用于生成计算sympy表达式的C,C ++,Fortran77,Fortran90,Julia,Rust和Octave / Matlab示例的模块。该模块正在进行中。以下列表中只有带有“ +”字符的里程碑已完成。

— sympy.utilities.codegen与sympy.printing.ccode有何不同?—

以扩展Sympy函数的打印示例的方式来打印完整的可编译代码,这会导致一些无法解决的问题,只有使用专用代码生成器才能解决:

  • 对于C语言,需要代码和头文件,而打印示例仅生成一个字符串。可以扩展此代码生成器以支持f2py的.pyf文件。
  • SymPy函数与编程技术问题无关,例如输入,输出和输入输出自变量。其它示例是连续或不连续的数组,包括其它库(例如gsl或其它库)的including headers。
  • 在一个C示例中评估几个sympy函数,最终在cse示例的帮助下共享共同的中间结果,这是非常有趣的。这不仅仅是打印。
  • 从编程的角度来看,应在代码生成器中尽可能多地评估具有常量的表达式。这与打印不同。

-基本假设-

  • 常规示例数据结构描述了必须转换为C / Fortran /…代码的示例。此数据结构涵盖以一种或多种支持的语言提供的所有功能。
  • CodeGen类的扩展将多个Routine实例转换为可编译代码。每个派生的类都翻译成一种特定的语言。
  • 在许多情况下,需要一个简单的工作流程。最后一部分中的友函数是Routine / CodeGen之上的简单api。它们更易于使用,但功能不那么强大。

—里程碑—

  • 具有标量输入参数的第一个工作版本,生成C代码,进行测试
  • 友好的功能比严格的Routine / CodeGen工作流程更易于使用。
  • 整数和实数作为输入和输出
  • 输出参数
  • Input Output参数
  • 正确排序输入/输出参数
  • 连续数组参数(numpy矩阵)
  • 同时为f2py生成.pyf代码(在自动包装模块中)
  • 隔离常数并事先以双精度对其求值
  • Fortran 90
  • Octave/Matlab
  • 常见子表达消除
  • 用户定义的注释在生成的代码中
  • 可选的依赖包含行,可以评估特殊功能的库/对象
  • 测试其它C编译器和库:gcc,tcc,libtcc,gcc + gsl等
  • 连续数组参数(对称矩阵)
  • 非连续数组参数(对称矩阵)
  • 当ccode遇到无法翻译为c的内容时,必须引发错误。ccode(integrate(sin(x)/ x,x))没有意义。
  • 复数作为输入和输出
  • 默认的复杂数据类型
  • Include中包含其它信息:日期,用户,主机名,sha1哈希,…
  • Fortran 77
  • C ++
  • Python
  • Julia
  • Rust

class sympy.utilities.codegen.Argument(name, datatype=None, dimensions=None, precision=None)

抽象的Argument数据结构:名称和数据类型。

下面的扩展对这种结构进行了改进。

class sympy.utilities.codegen.CCodeGen(project='project', printer=None, preprocessor_statements=None, cse=False)

C代码生成器。

从CodeGen继承的.write()方法,将分别输出代码文件和接口文件<prefix> .c和<prefix> .h。

dump_c(routines, f, prefix, header=True, empty=True)

通过调用特定于语言的方法来编写代码。

生成的文件以低级代码包含示例的所有定义,并在适当时引用头文件。

参量

示例:列表

示例实例列表。

f:类似文件

在哪里写文件。

前缀:字符串

文件名前缀,用于引用正确的头文件。仅使用前缀的基本名称。

header:布尔值,可选

如果为True,则在每个源文件的顶部包含标题注释。[默认:正确]

:布尔值,可选

如果为True,则包含空行以构造源文件。[默认:正确]

dump_h(routines, f, prefix, header=True, empty=True)

写入C头文件。

该文件包含所有函数声明。

参量

示例:列表

示例实例列表。

f:类似文件

在哪里写文件。

前缀:字符串

文件名前缀,用于构造包含include guards保护。仅使用前缀的基本名称。

header:布尔值,可选

如果为True,则在每个源文件的顶部包含标题注释。[默认:正确]

:布尔值,可选

如果为True,则包含空行以构造源文件。[默认:正确]

get_prototype常规

返回该示例的函数原型的字符串。

如果示例具有多个结果对象,则会引发CodeGenError。

请参阅:https//en.wikipedia.org/wiki/Function_prototype

class sympy.utilities.codegen.CodeGen(project='project', cse=False)

代码生成器的抽象类。

dump_code(routines, f, prefix, header=True, empty=True)

通过调用特定于语言的方法来编写代码。

生成的文件以低级代码包含示例的所有定义,并在适当时引用头文件。

参量

示例:列表

示例列表。

f:类似文件

在哪里写文件。

前缀:字符串

文件名前缀,用于引用正确的头文件。仅使用前缀的基本名称。

header:布尔值,可选

如果为True,则在每个源文件的顶部包含标题注释。[默认:正确]

:布尔值,可选

如果为True,则包含空行以构造源文件。[默认:正确]

routine(name, expr, argument_sequence=None, global_vars=None)

创建适合该语言的Routine对象。

此实现至少适用于C / Fortran。如有必要,子类可以覆盖此方法。

假设最多有一个返回值(l值),必须是标量。其它输出是OutputArguments(例如,右侧的指针或通过引用的指针)。矩阵始终通过OutputArguments返回。如果argument_sequence为None,则参数将按字母顺序排序,但所有InputArguments排第一,然后是OutputArgument和InOutArguments。

write(routines, prefix, to_files=False, header=True, empty=True)

编写给定示例的所有源代码文件。

生成的源作为(文件名,内容)元组的列表返回,或写入文件中(请参见下文)。每个文件名都由给定的前缀组成,并附加适当的扩展名。

参量

示例:列表

要编写的示例实例列表

前缀:字符串

输出文件的前缀

to_files:布尔值,可选

为True时,输出将写入文件。否则,将返回(文件名,内容)元组的列表。[默认值:False]

header:布尔值,可选

如果为True,则在每个源文件的顶部包含标题注释。[默认值:True]

:布尔值,可选

如果为True,则包含空行以构造源文件。[默认值:True]

class sympy.utilities.codegen.DataType(cname, fname, pyname, jlname, octname, rsname)

以不同的语言保存某个数据类型的字符串。

class sympy.utilities.codegen.FCodeGen(project='project', printer=None)

Fortran 95代码生成器

从CodeGen继承的.write()方法将分别输出代码文件和接口文件<prefix> .f90和<prefix> .h。

dump_f95(routines, f, prefix, header=True, empty=True)

通过调用特定于语言的方法来编写代码。

生成的文件以低级代码包含示例的所有定义,并在适当时引用头文件。

参量

示例:列表

示例实例列表。

f:类似文件

在哪里写文件。

前缀:字符串

文件名前缀,用于引用正确的头文件。仅使用前缀的基本名称。

header:布尔值,可选

如果为True,则在每个源文件的顶部包含标题注释。[默认:正确]

:布尔值,可选

如果为True,则包含空行以构造源文件。[默认:正确]

dump_h(routines, f, prefix, header=True, empty=True)

将接口写入头文件。

该文件包含所有函数声明。

参量

示例:列表

示例实例列表。

f:类似文件

在哪里写文件。

前缀:字符串

文件名前缀。

header:布尔值,可选

如果为True,则在每个源文件的顶部包含标题注释。[默认:正确]

:布尔值,可选

如果为True,则包含空行以构造源文件。[默认:正确]

get_interface常规

返回函数接口的字符串。

该示例应具有单个结果对象,该对象可以为None。如果示例具有多个结果对象,则会引发CodeGenError。

请参阅:https//en.wikipedia.org/wiki/Function_prototype

class sympy.utilities.codegen.JuliaCodeGen(project='project', printer=None)

从CodeGen继承的.write()方法将输出代码文件<prefix> .jl。

dump_jl(routines, f, prefix, header=True, empty=True)

通过调用特定于语言的方法来编写代码。

生成的文件以低级代码包含示例的所有定义,并在适当时引用头文件。

参量

示例:列表

示例实例列表。

f:类似文件

在哪里写文件。

前缀:字符串

文件名前缀,用于引用正确的头文件。仅使用前缀的基本名称。

header:布尔值,可选

如果为True,则在每个源文件的顶部包含标题注释。[默认:正确]

:布尔值,可选

如果为True,则包含空行以构造源文件。[默认:正确]

routine(name, expr, argument_sequence, global_vars)

专为Julia创建例行程序。

class sympy.utilities.codegen.OctaveCodeGen(project='project', printer=None)

从CodeGen继承的.write()方法将输出代码文件<prefix> .m。

octave.m文件通常包含一个功能。该函数名称应与文件名(prefix)相匹配。如果传递多个name_expr对,则假定后者是由主函数访问的私有函数。

只应将输入传递给argument_sequence:输出按照name_expr中的顺序排列。

dump_m(routines, f, prefix, header=True, empty=True, inline=True)

通过调用特定于语言的方法来编写代码。

生成的文件以低级代码包含示例的所有定义,并在适当时引用头文件。

参量

示例:列表

示例实例列表。

f:类似文件

在哪里写文件。

前缀:字符串

文件名前缀,用于引用正确的头文件。仅使用前缀的基本名称。

header:布尔值,可选

如果为True,则在每个源文件的顶部包含标题注释。[默认:正确]

:布尔值,可选

如果为True,则包含空行以构造源文件。[默认:正确]

routine(name, expr, argument_sequence, global_vars)

octave的专业示例创建。

class sympy.utilities.codegen.OutputArgument(name, result_var, expr, datatype=None, dimensions=None, precision=None)

OutputArgument总是在示例中初始化。

class sympy.utilities.codegen.Result(expr, name=None, result_var=None, datatype=None, dimensions=None, precision=None)

返回值的表达式。

名称结果用于避免与python语言中的保留字“ return”发生冲突。也比ReturnValue短。

可能在目标中也可能不需要名称(例如,“ return(x * y)”可能会返回一个值而无需命名)。

class sympy.utilities.codegen.Routine(name, arguments, results, local_vars, global_vars)

表达式集的评估示例的一般描述。

CodeGen类可以将此类的实例转换为特定语言的代码。常规规范涵盖了这些语言中存在的所有功能。当目标语言中不存在某些功能时,CodeGen部分必须引发异常。例如,在Python中可能有多个返回值,但在C或Fortran中却没有。另一个示例:Fortran和Python支持复数,而C不支持。

属性result_variables

返回OutputArgument,InOutArgument和Result的列表。

如果存在返回值,则它们将位于列表的末尾。

属性variables

返回示例中可能使用的所有变量的集合。

对于具有未命名返回值的示例,可能使用或可能不使用的虚拟变量将包括在该集合中。

class sympy.utilities.codegen.RustCodeGen(project='project', printer=None)

Rust代码生成器。

从CodeGen继承的.write()方法将输出代码文件<prefix> .rs

dump_rs(routines, f, prefix, header=True, empty=True)

通过调用特定于语言的方法来编写代码。

生成的文件以低级代码包含示例的所有定义,并在适当时引用头文件。

参量

示例:列表

示例实例列表。

f:类似文件

在哪里写文件。

前缀:字符串

文件名前缀,用于引用正确的头文件。仅使用前缀的基本名称。

header:布尔值,可选

如果为True,则在每个源文件的顶部包含标题注释。[默认:正确]

:布尔值,可选

如果为True,则包含空行以构造源文件。[默认:正确]

get_prototype常规

返回该示例的函数原型的字符串。

如果示例具有多个结果对象,则会引发CodeGenError。

请参阅:https//en.wikipedia.org/wiki/Function_prototype

routine(name, expr, argument_sequence, global_vars)[source]

Rust的常规程序创建。

sympy.utilities.codegen.codegen(name_expr, language=None, prefix=None, project='project', to_files=False, header=True, empty=True, argument_sequence=None, global_vars=None, standard=None, code_gen=None, printer=None)

为给定语言的表达式生成源代码。

参量

name_expr:元组或元组列表

一个(名称,表达式)元组或(名称,表达式)元组列表。每个元组对应一个示例。如果表达式是等式(Equal类的实例),则将左侧视为输出参数。如果expression是可迭代的,则该示例将具有多个输出。

语言:字符串,

指示源代码语言的字符串。这是不区分大小写的。当前,支持“ C”,“ F95”和“Octave”。“ Octave”生成与Octave和Matlab兼容的代码。

prefix:字符串,可选

包含源代码的文件名的前缀。与语言相关的后缀将被附加。如果省略,则使用第一个name_expr元组的名称。

项目:字符串,可选

项目名称,用于制作唯一的预处理程序指令。[默认:“项目”]

to_files:布尔值,可选

当为True时,代码将被写入具有给定前缀的一个或多个文件,否则返回具有这些文件的名称和内容的字符串。[默认值:False]

标头:布尔值,可选

如果为True,则将标头写入每个源文件的顶部。[默认值:True]

:布尔值,可选

如果为True,则使用空行来构造代码。[默认值:True]

arguments_sequence:可迭代,可选

示例的参数序列按首选顺序排列。如果缺少必需的参数,则会引发CodeGenError。使用冗余参数时不会发出警告。如果省略,则参数将按字母顺序排序,但所有输入参数都将首先排列,然后是输出或输入-输出参数。

global_vars:可迭代,可选

示例使用的全局变量序列。此处列出的变量不会显示为函数参数。

标准:字符串

code_gen:CodeGen实例

CodeGen子类的实例。覆盖language。

示例

Run code block in SymPy Live

>>> from sympy.utilities.codegen import codegen

>>> from sympy.abc import x, y, z

>>> [(c_name, c_code), (h_name, c_header)] = codegen(

...     ("f", x+y*z), "C89", "test", header=False, empty=False)

>>> print(c_name)

test.c

>>> print(c_code)

#include "test.h"

#include <math.h>

double f(double x, double y, double z) {

double f_result;

f_result = x + y*z;

return f_result;

}

>>> print(h_name)

test.h

>>> print(c_header)

#ifndef PROJECT__TEST__H

#define PROJECT__TEST__H

double f(double x, double y, double z);

#endif

使用Equality对象提供命名输出的另一个示例。这里的文件名(前缀)取自first (name, expr)。

Run code block in SymPy Live

>>> from sympy.abc import f, g

>>> from sympy import Eq

>>> [(c_name, c_code), (h_name, c_header)] = codegen(

...      [("myfcn", x + y), ("fcn2", [Eq(f, 2*x), Eq(g, y)])],

...      "C99", header=False, empty=False)

>>> print(c_name)

myfcn.c

>>> print(c_code)

#include "myfcn.h"

#include <math.h>

double myfcn(double x, double y) {

double myfcn_result;

myfcn_result = x + y;

return myfcn_result;

}

void fcn2(double x, double y, double *f, double *g) {

(*f) = 2*x;

(*g) = y;

}

如果生成的函数将是已定义各种全局变量的较大项目的一部分,则可以使用'global_vars'选项从函数签名中删除指定的变量

Run code block in SymPy Live

>>> from sympy.utilities.codegen import codegen

>>> from sympy.abc import x, y, z

>>> [(f_name, f_code), header] = codegen(

...     ("f", x+y*z), "F95", header=False, empty=False,

...     argument_sequence=(x, y), global_vars=(z,))

>>> print(f_code)

REAL*8 function f(x, y)

implicit none

REAL*8, intent(in) :: x

REAL*8, intent(in) :: y

f = x + y*z

end function

sympy.utilities.codegen.get_default_datatype(expr, complex_allowed=None)

根据表达式得出适当的数据类型。

sympy.utilities.codegen.make_routine(name, expr, argument_sequence=None, global_vars=None, language='F95')

通过表达式生成适当示例的factory。

参量

名称:字符串

生成的代码中此示例的名称。

expr:表达式或表达式列表/元组

Routine实例将代表的SymPy表达式。如果给定表达式列表或元组,则该示例将被视为具有多个返回值和/或输出参数。

arguments_sequence:列表或元组,可选

以首选顺序列出示例的参数。如果省略,则结果取决于语言,例如,字母顺序或与给定表达式相同的顺序。

global_vars:可迭代,可选

示例使用的全局变量序列。此处列出的变量不会显示为函数参数。

语言:字符串,可选

指定目标语言。示例本身应该与语言无关,但是创建示例的确切方式,错误检查等取决于语言。[默认值:“ F95”]。

决定是否使用输出参数或返回值

取决于语言和特定的数学表达式。

对于Equality类型的表达式,通常制作左侧

放入一个OutputArgument(或一个InOutArgument,如果合适的话)。

否则,通常使计算出的表达式的返回值为

routine程序。

示例

Run code block in SymPy Live

>>> from sympy.utilities.codegen import make_routine

>>> from sympy.abc import x, y, f, g

>>> from sympy import Eq

>>> r = make_routine('test', [Eq(f, 2*x), Eq(g, x + y)])

>>> [arg.result_var for arg in r.results]

[]

>>> [arg.name for arg in r.arguments]

[x, y, f, g]

>>> [arg.name for arg in r.result_variables]

[f, g]

>>> r.local_vars

set()

另一个更复杂的示例,其中包含指定名称和自动分配的名称。还具有矩阵输出。

Run code block in SymPy Live

>>> from sympy import Matrix

>>> r = make_routine('fcn', [x*y, Eq(f, 1), Eq(g, x + g), Matrix([[x, 2]])])

>>> [arg.result_var for arg in r.results]

[result_5397460570204848505]

>>> [arg.expr for arg in r.results]

[x*y]

>>> [arg.name for arg in r.arguments]

[x, y, f, g, out_8598435338387848786]

可以更仔细地研究各种论点:

Run code block in SymPy Live

>>> from sympy.utilities.codegen import (InputArgument, OutputArgument,

...                                      InOutArgument)

>>> [a.name for a in r.arguments if isinstance(a, InputArgument)]

[x, y]

Run code block in SymPy Live

>>> [a.name for a in r.arguments if isinstance(a, OutputArgument)]

[f, out_8598435338387848786]

>>> [a.expr for a in r.arguments if isinstance(a, OutputArgument)]

[1, Matrix([[x, 2]])]

Run code block in SymPy Live

>>> [a.name for a in r.arguments if isinstance(a, InOutArgument)]

[g]

>>> [a.expr for a in r.arguments if isinstance(a, InOutArgument)]

[g + x]

代码生成codegen的更多相关文章

  1. TVM代码生成codegen

    TVM代码生成codegen 硬件后端提供程序(例如Intel,NVIDIA,ARM等),提供诸如cuBLAS或cuDNN之类的内核库以及许多常用的深度学习内核,或者提供框架例,如带有图形引擎的DNN ...

  2. 从Swift桥接文件到Clang-LLVM

    http://blog.csdn.net/u014795020/article/details/72514109 前言 今天在Swift工程中不小心创建了一个OC文件,于是乎提示我创建一个桥接文件,那 ...

  3. 基于 Eclipse 平台的代码生成技术

    ------------------------------------------------------------------ 转自http://www.ibm.com/developerwor ...

  4. Eclipse Axis2 插件将代码生成WSDL指南

    Eclipse Axis2 插件将代码生成WSDL指南 快速学习手册 开发工具:https://spring.io/tools 插件地址:http://axis.apache.org/axis2/ja ...

  5. 从零写一个编译器(十三):代码生成之遍历AST

    项目的完整代码在 C2j-Compiler 前言 在上一篇完成对JVM指令的生成,下面就可以真正进入代码生成部分了.通常现代编译器都是先把生成IR,再经过代码优化等等,最后才编译成目标平台代码.但是时 ...

  6. ent 基本使用九 代码生成

    ent 提供了cli 工具,可以方便我们进行schema 以及代码生成,同时目前提供的cli已经够用了 安装 cli go get github.com/facebookincubator/ent/c ...

  7. TVM设备添加以及代码生成

    因为要添加的设备是一种类似于GPU的加速卡,TVM中提供了对GPU编译器的各种支持,有openCl,OpenGL和CUDA等,这里我们选取比较熟悉的CUDA进行模仿生成.从总体上来看,TVM是一个多层 ...

  8. 从"UDF不应有状态" 切入来剖析Flink SQL代码生成

    从"UDF不应有状态" 切入来剖析Flink SQL代码生成 目录 从"UDF不应有状态" 切入来剖析Flink SQL代码生成 0x00 摘要 0x01 概述 ...

  9. [源码分析]从"UDF不应有状态" 切入来剖析Flink SQL代码生成 (修订版)

    [源码分析]从"UDF不应有状态" 切入来剖析Flink SQL代码生成 (修订版) 目录 [源码分析]从"UDF不应有状态" 切入来剖析Flink SQL代码 ...

随机推荐

  1. hdu4544 优先队列(小贪心)

    题意: 湫湫系列故事--消灭兔子                                                                         Time Limit: ...

  2. Windows核心编程 第十七章 -内存映射文件(上)

    第1 7章 内存映射文件 对文件进行操作几乎是所有应用程序都必须进行的,并且这常常是人们争论的一个问题.应用程序究竟是应该打开文件,读取文件并关闭文件,还是打开文件,然后使用一种缓冲算法,从文件的各个 ...

  3. coding push 上传文件

    git config --global user.name "lyshark" &git config --global user.email "11815068 ...

  4. Root mapping definition has unsupported parameters

    使用ElasticSearch创建映射报错 Root mapping definition has unsupported parameters 原因 使用的ES版本为7.2.0,不再支持创建指定类型 ...

  5. Linux防火墙放行端口

    添加放行端口 firewall-cmd --zone=public --add-port=端口号/tcp --permanent 重启防火墙 systemctl restart firewalld.s ...

  6. Spring的配置文件 (SSM maven项目)

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  7. svn客户端访问失败,错误“请求的名称有效,但是找不到请求的类型”的解决

    1.问题描述:visualSVN客户端在其他机子访问出现以下问题(服务端装在我的电脑上,我本机客户端可以正常访问) 2. 原因分析:SVN客户端访问服务器需要输入URL地址,URL地址分为两种方式.一 ...

  8. Beta设计和计划 —— NameNotFound

    需求再分析 1. 用户群体 经过用户(大多数是同学)的反馈,我们发现大家其实并不是十分明确我们要做的到底是什么.具体要怎么用.而实际上我们的典型用户也并不是学生群体,因此出现这些偏差也是很正常的,毕竟 ...

  9. Java7中Switch为什么只支持byte、short、char、int、String

    Java 7中,switch的参数可以是String类型了,这对我们来说是一个很方便的改进.到目前为止switch支持这样几种数据类型:byte short int char String .但是,作 ...

  10. [MySQL数据库之Navicat.pymysql模块、视图、触发器、存储过程、函数、流程控制]

    [MySQL数据库之Navicat.pymysql模块.视图.触发器.存储过程.函数.流程控制] Navicat Navicat是一套快速.可靠并价格相当便宜的数据库管理工具,专为简化数据库的管理及降 ...