我目前使用Cython链接C和Python,并在慢速的python代码中获得加速.但是,我想使用goroutine来实现一个非常慢(并且非常可并行化)的代码,但它必须可以从python中调用.(我已经看过这个问题)
我(在某种程度上)乐意通过C(或用Cython)去,如果需要建立数据结构等,但避免这种额外的层将是从一个bug修复/避让点好.
无需重新发明轮子,最简单的方法是什么?
我真的很难过这个.
我有一个简单的python包装器,看起来像这样:
import glob
for found in glob.glob(filename):
if not os.path.isdir(found):
my_module.do_stuff(found)
Run Code Online (Sandbox Code Playgroud)
从哪里filename读入sys.argv.
当我尝试glob使用交互式shell或hello world脚本时,我会获得(在这种情况下为5个)文件的完整列表.但是,当我在这种情况下使用它时,我只获得第一个(按字母顺序).
我已经通过捕获glob.glob数组中的结果来检查,果然,它只有len()1,即使文件名只是'*'.
我可能会做什么打破glob?!
完整的代码文件,万一你可以发现我的问题:
#! /usr/bin/python
import pynet.quadrons as q
import os, glob
def print_usage():
print """
(blah blah big long string.)
"""
if __name__ == "__main__":
import sys
if len(sys.argv) < 2:
print_usage()
exit()
filename = ''
try:
filename = sys.argv[1]
except:
print "error parsing arguments."
print_usage()
exit()
for found in …Run Code Online (Sandbox Code Playgroud) 我在这里寻找的可能是一个内置函数networkx,并有一个数学名称 - 如果是这样,我想知道它是什么!看起来谷歌很难实现.
给定一个图形G和一个起始节点i,我想找到所有节点"在P边缘内" 的子图i- 即那些i通过小于P边的路径连接的节点.
我的实施草案是:
import networkx as nx
N = 30
G = nx.Graph()
# populate the graph...
G.add_cycle(range(N))
# the starting node:
i = 15
# the 'distance' limit:
P = 4
neighborhood = [i]
new_neighbors = [i]
depth = 0
while depth < P:
new_neighbors = list(set(sum([
[k for k in G[j].keys() if k not in neighborhood]
for j in new_neighbors], …Run Code Online (Sandbox Code Playgroud) 最终更新
这个问题是关于如何编写一个setup.py将编译一个直接访问FORTRAN代码的cython模块,就像C一样.这是一个相当漫长而艰巨的解决方案之旅,但下面包含完整的混乱情况.
原始问题
我有一个扩展,它是一个Cython文件,它设置一些堆内存并将其传递给fortran代码,以及一个fortran文件,这是一个古老的模块,我想避免重新实现,如果可以的话.
该.pyx文件可以很好地编译为C,但是cython编译器会对.f90文件进行扼流,并出现以下错误:
$ python setup.py build_ext --inplace
running build_ext
cythoning delaunay/__init__.pyx to delaunay/__init__.c
building 'delaunay' extension
error: unknown file type '.f90' (from 'delaunay/stripack.f90')
Run Code Online (Sandbox Code Playgroud)
这是我的安装文件的(上半部分):
from distutils.core import setup, Extension
from Cython.Distutils import build_ext
ext_modules = [
Extension("delaunay",
sources=["delaunay/__init__.pyx",
"delaunay/stripack.f90"])
]
setup(
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules,
...
)
Run Code Online (Sandbox Code Playgroud)
注意:我最初错误地指定了fortran文件的位置(没有目录前缀),但是在我修复之后,这种方式完全相同.
我尝试过的事情:
我找到了这个,并尝试传递fortran编译器(即gfortran)的名称,如下所示:
$ python setup.py config --fcompiler=gfortran build_ext --inplace
usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
or: …Run Code Online (Sandbox Code Playgroud) 我在OS X 10.7 Lion上安装了所有的开发工具,但是当我在一个相对简单的程序上运行GCC时,只需要通过几次调用openCL函数等直接C clCreateProgramFromSource,我得到以下错误列表:
Undefined symbols for architecture x86_64:
"_CreateContext", referenced from:
_build_kernel in ccFuZYMI.o
"_GetDevices", referenced from:
_build_kernel in ccFuZYMI.o
"_CreateCommandQueue", referenced from:
_build_kernel in ccFuZYMI.o
"_clCreateProgramWithSource", referenced from:
_build_kernel in ccFuZYMI.o
"_clBuildProgram", referenced from:
_build_kernel in ccFuZYMI.o
"_clCreateKernel", referenced from:
_build_kernel in ccFuZYMI.o
"_clCreateBuffer", referenced from:
_build_kernel in ccFuZYMI.o
"_clEnqueueWriteBuffer", referenced from:
_sync_run_kernel in ccFuZYMI.o
"_clSetKernelArg", referenced from:
_sync_run_kernel in ccFuZYMI.o
"_clEnqueueNDRangeKernel", referenced from:
_sync_run_kernel in ccFuZYMI.o
"_clEnqueueReadBuffer", referenced from:
_sync_run_kernel in ccFuZYMI.o
"_clReleaseContext", referenced from: …Run Code Online (Sandbox Code Playgroud) 我正在努力让一些开源学术代码工作(项目主页在这里).它是一个很大的C++代码库,带有(非常)瘦的python包装器,用于CDLL加载C++并调用一些可用的C函数来允许代码的原始python脚本.
但是,初始导入代码崩溃,因为它无法在site-packages中找到它旁边的.so文件:
在已安装的文件中:
from ctypes import *
try:
self.lib = CDLL("_lammps.so")
except:
try:
self.lib = CDLL("_lammps_serial.so")
except:
raise OSError,"Could not load LAMMPS dynamic library"
Run Code Online (Sandbox Code Playgroud)
并在脚本或解释器中:
from lammps import lammps
l = lammps()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lammps.py", line 42, in __init__
raise OSError,"Could not load LAMMPS dynamic library"
OSError: Could not load LAMMPS dynamic library
Run Code Online (Sandbox Code Playgroud)
其他的答案似乎已经本公约所涵盖的,但如果这只能CDLL()是在脚本中调用实际调用(或跑解释提示的工作目录) -即如果"相对路径"是在用户空间,而不是蟒蛇库空间.
我们如何可靠地安装导入我们自己构建的C/C++库?没有污染系统库位置,如/usr/lib不是非常pythonic,我看不到一个简单的解决方案.
(编辑:更正的函数名称,不明确的重构无益!抱歉!)
创建了一个由许多源文件和头文件组成的 C 库后,我现在需要用 Python 层包装它,以便我可以“导入”它。
我已经实现了从 Python 调用的静态方法,并且我需要指定模块应向解释器公开哪些方法。
然而,在指定可以调用的内容时,文档似乎只处理具有单个源文件的非常简单的情况,因为唯一的非静态方法必须是 init,它注册方法。
据我所知,如果其他源文件中的方法在 C 中声明为静态,则不可能调用它们(如果我错了,请纠正我),因此,每个 python 模块只能有一个 C 文件,因为整个过程中只允许使用一种非静态方法。
事实真的如此吗?如果你想从 Python 访问你的代码,你的代码结构必须很糟糕/根本不需要吗?
编辑:
因此,我最终实现此目的的方法是使用Cython。重写 c/python 接口不仅需要大约一个小时(由于所有引用计数规则等原因,之前需要大约一天的时间),而且它还为您处理所有构建问题,并且有清晰的文档准确描述了哪些问题方法可以从 python 获得。
特别是,我使用的文档章节包括构建说明、如何调用 C 库、语言基础知识以及如何转换类型(尤其是指针)。
对于任何想要将现有的复杂结构 C 代码(即不仅仅是单个文件的代码)包装为 python 库的人,我强烈推荐 Cython。
我不是在写游戏,而是使用Pygame进行科学渲染.我希望控件能够像第一人称射击游戏一样工作,这样用户就可以使用熟悉的控件进行导航.
我试图编写代码,使其具有与"天际"或"半条命"中的"外观"功能相同的属性,但鼠标不会移动光标 - 它可以让您以无限的圆圈环顾四周.单击应该没有效果.
控件的第一次尝试:
(游戏循环中的代码)
delta_y, delta_x = pygame.mouse.get_rel()
rotation_direction.x = float(delta_x)
rotation_direction.y = float(delta_y)
Run Code Online (Sandbox Code Playgroud)
(不要问我为什么,但是y和x需要像这样反转以获得预期的外观方向;必须与相机变换实现有关,这不是我的.)
然而,这导致光标位于窗口顶部,当光标到达屏幕边缘时,窗口停止旋转; 即代码报告屏幕上的实际位置.
我尝试在每个游戏循环中"重置"鼠标位置(顺便提一下,隐藏鼠标):
pygame.mouse.set_pos([150, 150])
pygame.mouse.set_visible(False)
Run Code Online (Sandbox Code Playgroud)
但是这会在下一个循环中产生对称的"向后移动"三角形,这意味着你无法在任何地方'看'.
总结一下,我想:
使用Pygame或其他Python黑客攻击的最佳方法是什么?
好的,所以我把它分解为一个非常具体的问题.
我的印象是你可以将OpenCL中任何类型的数据传递给数组缓冲区; int,chars,你自己的自定义结构,只要它只是数据而且不包含指向GPU无法检索的堆对象的指针.
现在,我已经尝试了这个,我认为它适用于大量的整数,但是我的结构数组失败了.特别,
cl_mem log_buffer = clCreateBuffer(context, CL_MEM_READ_WRITE,
num_elements * sizeof(int), NULL, NULL);
int* error_codes_in = (int*)malloc(num_elements * sizeof(int));
for (i = 0; i < num_elements; i++) {
error_codes_in[i] = i;
}
error = clEnqueueWriteBuffer(command_queue, log_buffer, CL_TRUE,
0, num_elements * sizeof(int), error_codes_in, 0, NULL, NULL);
Run Code Online (Sandbox Code Playgroud)
这很好用,我在GPU上获得了一组数字,可以并行地成功操作它们.
但是,当我使用自己的自定义结构时:
typedef struct {
float position[2];
float velocity[2];
float radius;
float resultant_force[2];
} ocl_element_2d_t;
Run Code Online (Sandbox Code Playgroud)
(也在内核中定义为)
const char* kernel_string =
"typedef struct { float position[2]; float velocity[2]; float radius; float resultant_force[2]; } ocl_element_2d_t;"...
Run Code Online (Sandbox Code Playgroud)
我使用相同/非常相似的代码写入我的struct数组的GPU版本: …
我正在尝试编写一个带有一些c和一些python部分的模块.我正在使用cython弥补差距.
我想在python中存储我的(非常长的)字符串常量,因为它的语法更好:
const char long_string = "\npart of string\n"
"next part\n"
"last part\n";
Run Code Online (Sandbox Code Playgroud)
与:
long_string = """
part of string
next part
last part
"""
Run Code Online (Sandbox Code Playgroud)
(字符串比这长得多,而且更复杂 - 我不希望每次我想用语法高亮来编辑它时都要添加和删除"s和\n"s.事实上,它们是openCL内核.)
我需要能够使用cython将它们变成c字符串,根据文档我应该只需要:
cdef bytes py_bytes = py_string.encode()
cdef char* c_string = py_bytes
Run Code Online (Sandbox Code Playgroud)
并且没有手动内存管理,c_string只要我保留引用就可以工作py_bytes.
但是,我无法使用简单的printf测试.这是我的cython文件:
cdef extern from "stdio.h":
printf(char* string)
def go():
py_string = """
a complicated string
with a few
newlines.
"""
cdef bytes py_bytes = py_string.encode()
cdef char* c_string = py_bytes …Run Code Online (Sandbox Code Playgroud) 所以我有一个看起来有点像这样的矢量类(大多数方法为了清晰起见而被剥离):
class D3Vector {
private:
double _values[3];
public:
const double& operator[](const int index) const;
double& operator[](const int index);
};
double& D3Vector::operator[](const int index) {
assert(index >= 0 && index < 3);
return _values[index];
}
const double& D3Vector::operator[](const int index) const {
assert(index >= 0 && index < 3);
return _values[index];
}
Run Code Online (Sandbox Code Playgroud)
在我的代码中的某些时候,我调用此数组下标重载如下:
void func(D3Vector centre, double radius) {
double limits[6];
int i;
for (i = 0; i < 3; i++) {
// both these lines cause the error...
limits[i] = …Run Code Online (Sandbox Code Playgroud) 一些指针算术有相当大的麻烦.我想我得到了概念(指针变量指向内存地址,正常变量指向数据)但我相信我的问题是语法(*, &, (*), *(),等)
我想要做的是构建一个自定义结构的动态数组(即指向堆结构的指针数组),我的接口提供两个方法,"ad_to_obj_array"(它接受要添加的对象,以及可以为null的数组为空)和"obj_array_dustbin"(它只是处理数组,也处理内容,堆objs).前者呈现如下.
对象的细节并不重要(并且结构已经被重命名)但是我对一般问题的解决方案如下,如果您能发现错误,我将不胜感激.编译器抱怨无效的左值,我尝试将RHS上的指针中的地址分配给堆结构指针数组中的指针值:
#define NUM_ELEM(x) (sizeof (x) / sizeof (*(x)))
obj* add_to_obj_array(obj* new_obj, obj* array)
{
int number_of_elements = 0;
if (array != NULL)
{
number_of_elements = NUM_ELEM(array);
}
obj* new_array = NULL;
/* note: I am expecting sizeof(new_obj) to return the size of an obj*
to go into the array of pointers. */
if ( NULL ==
(new_array = (obj*)malloc((number_of_elements + 1)* sizeof(new_obj))) )
{
/* memory request refused :( */
return …Run Code Online (Sandbox Code Playgroud)