cython代码编译和setup.py文件编写

2023-11-12

Cython

官方文档: https://cython.readthedocs.io/en/latest/

中文文档:https://www.bookstack.cn/read/cython-doc-zh/
                   https://cython.apachecn.org/#/

构建 Cython 代码

与 Python 不同,Cython 代码必须编译。这发生在两个阶段:

.pyx文件由 Cython 编译为.c文件,包含 Python 扩展模块的代码。

.c文件由 C 编译器编译为.so文件(或 Windows 上的.pyd),可直接import直接进入 Python 会话.

构建 Cython 代码的几种方法:

  • 写一个 distutils / setuptools setup.py。推荐的方式。
  • 使用 Pyximport,导入 Cython .pyx文件就像它们是.py文件一样(使用 distutils 在后台编译和构建)。这种方法比编写setup.py更容易,但不是很灵活。因此,如果您需要某些编译选项,则需要编写setup.py
  • 手动运行cython命令行实用程序,从.pyx文件生成.c文件,然后手动将.c文件编译成适合从 Python 导入的共享库或 DLL。(这些手动步骤主要用于调试和实验。)
  • 使用 [Jupyter] 笔记本或 [Sage] 笔记本,两者都允许 Cython 代码内联。这是开始编写 Cython 代码并运行它的最简单方法。

 

手动从命令行编译

有两种从命令行编译的方法:

cython命令获取.py.pyx文件并将其编译为 C / C ++文件。

cythonize命令获取.py.pyx文件并将其编译为 C / C ++文件。然后,它将 C / C ++文件编译为可直接从 Python 导入的扩展模块。

cython命令进行编译

一种方法是使用 Cython 编译器手动编译它,例如:

$ cython primes.pyx

生成一个名为primes.c的文件,然后需要使用适合您平台的任何选项使用 C 编译器编译该文件以生成扩展模块(例如gcc)。

cythonize命令进行编译

cythonize -a -i yourmod.pyx

这将创建一个yourmod.c文件(或 C ++模式下的yourmod.cpp),对其进行编译,并将生成的扩展模块(.so.pyd,具体取决于您的平台)放在源文件旁边以进行直接导入(-i builds “in place””)。 -a 另外生成源代码的带注释的 html 文件。cythonize命令接受多个源文件和类似**/*.pyx的 glob 模式作为参数,并行构建作业的常用-j选项。在没有其他选项的情况下调用时,它只会将源文件转换为.c.cpp文件。传递-h标志以获取支持选项的完整列表。

distutils 构建 Cython 模块

def say_hello_to(name):
    print("Hello %s!" % name)

相应的setup.py脚本:

from distutils.core import setup
from Cython.Build import cythonize
setup(name='Hello world app',
      ext_modules=cythonize("hello.pyx"))

运行python setup.py build_ext --inplace。然后只需启动一个 Python 会话并执行from hello import say_hello_to并根据需要使用导入的函数。

如果您使用 setuptools 而不是 distutils,则需要注意,运行python setup.py install时的默认操作是创建一个压缩的egg文件,当您尝试从依赖包中使用它们时,这些文件无法与pxd文件一起用于pxd文件。为防止这种情况,请在setup()的参数中包含zip_safe=False

如果需要指定编译器选项,要链接的库或其他链接器选项,则需要手动创建Extension实例(请注意,glob 语法仍可用于在一行中指定多个扩展名): 

from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
extensions = [
    Extension("primes", ["primes.pyx"],
        include_dirs=[...],
        libraries=[...],
        library_dirs=[...]),
    # Everything but primes.pyx is included here.
    Extension("*", ["*.pyx"],
        include_dirs=[...],
        libraries=[...],
        library_dirs=[...]),
]
setup(
    name="My hello app",
    ext_modules=cythonize(extensions),

使用 setuptools 时,您应该在 Cython 之前导入它,因为 setuptools 可能会替换 distutils 中的Extension

Cythonize参数 https://www.bookstack.cn/read/cython-doc-zh/docs-29.md

Cython.Build.cythonize(module_listexclude=Nonenthreads=0aliases=Nonequiet=Falseforce=Falselanguage=Noneexclude_failures=Falseshow_all_warnings=False**options)

  • module_list –作为模块列表,传递全局模式,全局模式列表或扩展对象列表。后者允许您通过常规distutils选项分别配置扩展。您还可以传递具有glob模式作为其源的Extension对象。然后,cythonize将解析该模式并为每个匹配文件创建扩展的副本。
  • exclude –当将glob模式传递作为module_list时,可以通过将某些模块名称传递到exclude选项中来显式排除某些模块名称。
  • nthreads –并行编译的并发构建数(需要multiprocessing模块)。
  • alias
  • quiet –如果为True,则Cython在编译过程中不会打印错误,警告或状态消息。
  • force –强制重新编译Cython模块,即使时间戳不表明需要重新编译也是如此。
  • language –要全局启用C ++模式,可以通过language='c++'。否则,这将基于编译器指令在每个文件级别确定。这仅影响基于文件名找到的模块。传入的扩展实例cythonize()将不会更改。建议使用编译器指令而不是此选项。# distutils: language = c++
  • exclude_failures –对于广泛的“尝试编译”模式,该模式将忽略编译失败并仅排除失败的扩展,请通过exclude_failures=True。请注意,这仅对编译.py文件有意义,这些文件也可以不经编译而使用。
  • show_all_warnings –默认情况下,并非所有Cython警告都会被打印。设置为true以显示所有警告。
  • annotate 
  • compiler_directives -允许集合中的编译器指令setup.py是这样的:compiler_directives={'embedsignature': True} 。请参阅编译器指令https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#compiler-directives

包中的多个 Cython 文件

要自动编译多个 Cython 文件而不显式列出所有这些文件,可以使用 glob 模式:

setup(
    ext_modules = cythonize("package/*.pyx")
)

cythonize()传递它们,也可以在Extension对象中使用 glob 模式:

extensions = [Extension("*", ["*.pyx"])]
setup(
    ext_modules = cythonize(extensions)
)

如果您有许多扩展并希望避免声明中的额外复杂性,您可以使用它们的正常 Cython 源声明它们,然后在不使用 Cython 时调用以下函数而不是cythonize()来调整 Extensions 中的源列表:

import os.path
def no_cythonize(extensions, **_ignore):
    for extension in extensions:
        sources = []
        for sfile in extension.sources:
            path, ext = os.path.splitext(sfile)
            if ext in ('.pyx', '.py'):
                if extension.language == 'c++':
                    ext = '.cpp'
                else:
                    ext = '.c'
                sfile = path + ext
            sources.append(sfile)
        extension.sources[:] = sources
    return extensions

另一个选择是使 Cython 成为系统的设置依赖项,并使用 Cython 的 build_ext 模块作为构建过程的一部分运行

setup(
    setup_requires=[
        'cython>=0.x',
    ],
    extensions = [Extension("*", ["*.pyx"])],
    cmdclass={'build_ext': Cython.Build.build_ext},
    ...
)

通过cmdclass,build_ext可以自定义,看一个pytorch版本中的fasterrcnn 源码的setup.py

# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------

import os
from os.path import join as pjoin
import numpy as np
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize

def find_in_path(name, path):
    "Find a file in a search path"
    # adapted fom http://code.activestate.com/recipes/52224-find-a-file-given-a-search-path/
    for dir in path.split(os.pathsep):
        binpath = pjoin(dir, name)
        if os.path.exists(binpath):
            return os.path.abspath(binpath)
    return None


def locate_cuda():
    """Locate the CUDA environment on the system

    Returns a dict with keys 'home', 'nvcc', 'include', and 'lib64'
    and values giving the absolute path to each directory.

    Starts by looking for the CUDAHOME env variable. If not found, everything
    is based on finding 'nvcc' in the PATH.
    """

    # first check if the CUDAHOME env variable is in use
    if 'CUDAHOME' in os.environ:
        home = os.environ['CUDAHOME']
        nvcc = pjoin(home, 'bin', 'nvcc')
    else:
        # otherwise, search the PATH for NVCC
        default_path = pjoin(os.sep, 'usr', 'local', 'cuda', 'bin')
        nvcc = find_in_path('nvcc', os.environ['PATH'] + os.pathsep + default_path)
        if nvcc is None:
            raise EnvironmentError('The nvcc binary could not be '
                                   'located in your $PATH. Either add it to your path, or set $CUDAHOME')
        home = os.path.dirname(os.path.dirname(nvcc))

    cudaconfig = {'home': home, 'nvcc': nvcc,
                  'include': pjoin(home, 'include'),
                  'lib64': pjoin(home, 'lib64')}
    for k, v in cudaconfig.iteritems():
        if not os.path.exists(v):
            raise EnvironmentError('The CUDA %s path could not be located in %s' % (k, v))

    return cudaconfig


CUDA = locate_cuda()

# Obtain the numpy include directory.  This logic works across numpy versions.
try:
    numpy_include = np.get_include()
except AttributeError:
    numpy_include = np.get_numpy_include()


def customize_compiler_for_nvcc(self):
    """inject deep into distutils to customize how the dispatch
    to gcc/nvcc works.

    If you subclass UnixCCompiler, it's not trivial to get your subclass
    injected in, and still have the right customizations (i.e.
    distutils.sysconfig.customize_compiler) run on it. So instead of going
    the OO route, I have this. Note, it's kindof like a wierd functional
    subclassing going on."""

    # tell the compiler it can processes .cu
    self.src_extensions.append('.cu')

    # save references to the default compiler_so and _comple methods
    default_compiler_so = self.compiler_so
    super = self._compile

    # now redefine the _compile method. This gets executed for each
    # object but distutils doesn't have the ability to change compilers
    # based on source extension: we add it.
    def _compile(obj, src, ext, cc_args, extra_postargs, pp_opts):
        print extra_postargs
        if os.path.splitext(src)[1] == '.cu':
            # use the cuda for .cu files
            self.set_executable('compiler_so', CUDA['nvcc'])
            # use only a subset of the extra_postargs, which are 1-1 translated
            # from the extra_compile_args in the Extension class
            postargs = extra_postargs['nvcc']
        else:
            postargs = extra_postargs['gcc']

        super(obj, src, ext, cc_args, postargs, pp_opts)
        # reset the default compiler_so, which we might have changed for cuda
        self.compiler_so = default_compiler_so

    # inject our redefined _compile method into the class
    self._compile = _compile


# run the customize_compiler
class custom_build_ext(build_ext):
    def build_extensions(self):
        customize_compiler_for_nvcc(self.compiler)
        build_ext.build_extensions(self)


ext_modules = [
    Extension(		
        "model.utils.cython_bbox",		
        ["model/utils/bbox.pyx"],		
        extra_compile_args={'gcc': ["-Wno-cpp", "-Wno-unused-function"]},		
        include_dirs=[numpy_include]		
    ),
    Extension(
        'pycocotools._mask',
        sources=['pycocotools/maskApi.c', 'pycocotools/_mask.pyx'],
        include_dirs = [np.get_include(), '../common'],
        extra_compile_args={'gcc': ['-Wno-cpp', '-Wno-unused-function', '-std=c99']},
    ),
]

setup(
    name='faster_rcnn',
    ext_modules=ext_modules,
    # inject our custom trigger
    cmdclass={'build_ext': custom_build_ext},
)

setup(name='pycocotools',
      packages=['pycocotools'],
      package_dir = {'pycocotools': 'pycocotools'},
      version='2.0',
      ext_modules=
          cythonize(ext_modules)
      )

Cython + distutils/setuptools 构建

关于编写setup来变异cython程序,有两个模块distutils和setuptools,distutils属于python的标准库,setuptools在distutils基础上补充扩展,并且更新维护也比较快,所以setuptools应该替代distutils.在看很多项目源码里还是使用distutils,主要还是因为它是标准库吧,setuptools是三方库还要安装.distutils的官方文档也标注是遗留版本.(https://docs.python.org/zh-cn/3/distutils/index.html#distutils-index)

编写setup文件

,这里不记录怎么分发安装,简单了解下setup文件,用来编译cython

分发一个foo文件中包含的名为的模块foo.py

from distutils.core import setup
setup(name='foo',
      version='1.0',
      py_modules=['foo'],
      )
py_modules 需要的模块列表,模块是通过模块名称而不是文件名指定的,其他的是元数据(名称,版本号)等.

setup的参数

参数名称

类型

name

包的名字

字符串

version

包的版本号;参见 distutils.version

字符串

dcription

单行的包的描述

字符串

long_description

更长的包描述

字符串

author

包的作者

字符串

author_email

包的作者的电子邮件

字符串

maintainer

当前维护者的名称(如果不同于作者)。请注意,如果提供了维护程序,则distutils会将其用作作者PKG-INFO

字符串

maintenanceer_email

当前维护者的电子邮件地址,如果不同与作者

字符串

url

包的URL(主页)

字符串

download_url

包的下载地址

字符串

packages

distutils将操作的Python软件包列表

字符串列表

py_modules

distutils 会操作的 Python 模块列表

字符串列表

scripts

要构建和安装的独立脚本文件的列表

字符串列表

ext_modules

要构建的 Python 扩展的列表

类 distutils.core.Extension 的实例的列表

classifiers

包的类别列表

字符串列表;有效的分类器列在PyPI上

distclass

要使用的类 Distribution 类

distutils.core.Distribution 的子类

script_name

setup.py 脚本名称 —— 默认为 sys.argv[0]

字符串

script_args

提供给安装脚本的参数

字符串列表

options

安装脚本的默认选项

字典

license

包的许可证

字符串

keywords

描述性元数据,请参阅 PEP 314

字符串列表或逗号分隔的字符串

platform

 

字符串列表或逗号分隔的字符串

cmdclass

命令名称到Command子类的映射

字典

datafile

要安装的数据文件列表

列表

package_dir

包到目录名称的映射

字典

#!/usr/bin/env python

from distutils.core import setup

setup(name='Distutils',
      version='1.0',
      description='Python Distribution Utilities',
      author='Greg Ward',
      author_email='gward@python.net',
      url='https://www.python.org/sigs/distutils-sig/',
      packages=['distutils', 'distutils.command'],
     )

packages  按包分发,其他的还是元数据,其中name最好是一定要到,如果安装的话生成的文件会是指定name的名字.          Setup函数的packages参数是一个列表,其中包含了Distutils需要处理(构建、发布、安装等)的所有包。要实现此目的,那么包名和目录名必须能够相互对应,比如包名是distutils,则意味着在发布的根目录(setup脚本所在目录)下存在distutils子目录;再比如在setup脚本中packages = ['foo'],意味着要在setup脚本所在目录下存在相应的foo目录和foo/__init__.py文件。
package_dir选项可以改变这种默认的对应规则。package_dir是个字典,其中的key是要安装的包名,如果为空,则表明是root package,value就是该包(key)对应的源码树的目录。

package_dir = {'':'lib'},
packages = ['foo']

则必须在目录中存在lib子目录,lib/foo子目录,以及文件lib/foo/__init__.py。所以源码树如下

setup.py
lib/
    foo/
        __init__.py
        foo.py

 另外一个例子,foo包对应lib目录,所以,foo.bar包就对应着lib/bar子目录。所以如果在setup.py中这么写:

package_dir = {'foo':'lib'},
      packages = ['foo','foo.bar']

则必须存在lib/__init__.py,  lib/bar/__init__.py文件。源码树如下: 

setup.py
lib/
    __init__.py
    foo.py
    bar/
        __init__.py
        bar.py

Python扩展模块必须指定扩展名,源文件以及所有编译/链接要求(包括目录,要链接的库等),通过ext_modules

如果不需要对编译器/链接器的附加说明,则描述此扩展非常简单:

Extension('foo', ['foo.c'])
from distutils.core import setup, Extension
setup(name='foo',
      version='1.0',
      ext_modules=[Extension('foo', ['foo.c'])],
      )
Extension('foo', ['src/foo1.c', 'src/foo2.c'])和 Extension('pkg.foo', ['src/foo1.c', 'src/foo2.c'])区别是生成的扩展名在文件系统中的位置
如果一个包下有多个扩展,而且要把这些扩展都放在统一的目录下,则可以使用ext_package关键字,比如下面的语句
setup(...,
      ext_package='pkg',
      ext_modules=[Extension('foo', ['src/foo.c']),
                   Extension('subpkg.bar', ['src/bar.c'])]
     )

如果扩展名include 在分发根目录下的目录中需要头文件,可以使用以下include_dirs选项

Extension('foo', ['foo.c'], include_dirs=['include'])

以使用define_macros和 undef_macros选项定义和取消定义预处理器宏 

Extension(...,
    define_macros=[('NDEBUG', '1'),
                    ('HAVE_STRFTIME', None)],
    undef_macros=['HAVE_FOO', 'HAVE_BAR'])

等于在每个C源文件的顶部都包含此代码:

#define NDEBUG 1
#define HAVE_STRFTIME
#undef HAVE_FOO
#undef HAVE_BAR

指定在构建扩展时要链接到的库,以及用于搜索这些库的目录。该libraries选项是要链接的库列表,library_dirs是在链接时搜索库runtime_library_dirs的目录列表,并且是在运行时搜索共享(动态加载)库的目录列表。

Extension(...,
          libraries=['gdbm', 'readline'])

Extension参数

参数名称

类型

name

扩展名的全名,包括所有软件包- 不是文件名或路径名,而是Python点分名称

字符串

source

相对于分发根(安装脚本所在的位置)的源文件名列表,以Unix形式(以斜杠分隔)以实现可移植性。源文件可以是C,C ++,SWIG(.i),特定于平台的资源文件,也可以是build_ext命令识别为Python扩展源的任何其他文件 。

字符串列表

include_dirs

搜索C / C ++头文件的目录列表(以Unix形式提供可移植性)

字符串列表

define_macros

要定义的宏列表;每个宏都是使用2元组定义的,其中value是用来定义它的字符串,或者是在没有特定值的情况下定义它的字符串(等效 于source或 在Unix C编译器命令行上)(name, value)None#define FOO-DFOO

元组列表

undef_macros

要明确取消定义的宏列表

字符串列表

library_dirs

在链接时搜索C / C ++库的目录列表

字符串列表

libraries

要链接的库名列表(不是文件名或路径)

字符串列表

runtime_library_dirs

在运行时搜索C / C ++库的目录列表(对于共享扩展,这是在加载扩展时)

字符串列表

extra_objects

要链接的其他文件列表(例如,“源”未暗示的目标文件,必须明确指定的静态库,二进制资源文件等)

字符串列表

extra_compile_args

在“源”中编译源文件时要使用的任何其他特定于平台和编译器的信息。对于需要命令行的平台和编译器,这通常是命令行参数的列表,但是对于其他平台,可以是任何东西。

字符串列表

extra_link_args

将目标文件链接在一起以创建扩展名(或创建新的静态Python解释器)时使用的所有其他特定于平台和编译器的信息。与“ extra_compile_args”类似的解释。

字符串列表

export_symbols

从共享扩展名导出的符号列表。并非在所有平台上都使用,对于Python扩展通常也不是必需的,Python扩展通常只导出一个符号: init+ extension_name。

字符串列表

depends

扩展名依赖的文件列表

字符串列表

language

扩展语言(即 'c''c++', 'objc')。如果未提供,将从源扩展中检测到。

字符串

optional

指定扩展中的构建失败不应中止构建过程,而只是跳过扩展。

布尔

 

Distutils简单示例 https://docs.python.org/zh-cn/3/distutils/examples.html

扩展 Distutils https://docs.python.org/zh-cn/3/distutils/extending.html

Distutils 可以通过各种方式扩展。 大多数扩展都采用新命令或现有命令的替换形式。 例如,可以编写新命令以支持新的特定于平台的包格式,但是可以修改现有命令的替换,以修改命令在包上的操作细节。

distutils 的大多数扩展都在想要修改现有命令的 setup.py 脚本中编写;其中许多只是简单地在 .py 文件以外添加了一些应当被拷贝到包中的文件后缀以便使用。

大多部 distutils 命令的实现都是 distutils.cmd.Command 类的子类。 新增命令可直接继承自 Command,而替换命令往往间接派生自 Command, 直接子类化它们所替换的命令。 所有命令都要求自 Command 派生。

from distutils.command.build_py import build_py as _build_py
from distutils.core import setup

class build_py(_build_py):
    """Specialized Python source builder."""

    # implement whatever needs to be different...

setup(cmdclass={'build_py': build_py},
      ...)

Setuptools文档 https://setuptools.readthedocs.io/en/latest/index.html

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

cython代码编译和setup.py文件编写 的相关文章

随机推荐

  • Sqli-labs之Less-34

    Less 34 基于错误 POST 单引号 字符型 addslashes 宽字节注入 这一关是POST型的注入 同样的将post传递过来的内容进行了转义处理 过滤了单引号 反斜杠 有之前的例子我们可以看到 df可以将转义的反斜杠给吃掉 而G
  • 数据结构 十进制和十六进制进制间的相互转换

    一 十进制转十六进制 例题 输入十进制数 654321 输出十六进制数 9FBF1 解题步骤 十进制数对16取余 因为最终结果是从下往上依次书写 说以我们可以利用栈的特性 先进 的后出 将余数存入栈中依次弹出 再将弹出的数进行拼接输出即可
  • C++迭代器-------array的基本用法总结

    基本用法中主要总结有 遍历和比较大小 注意 加上头文件 include
  • 利用python来制作动态二维码

    前言 为什么要学习python 是因为不仅很多工作需要用到python 同时我们可以利用python做很多好玩儿的事儿 今天就来教大家如何利用python制作动态二维码 代码说明 我们以小猪佩奇gif图片为例 如果我们利用的背景图是gif动
  • 工厂实施MES系统可以带来哪些效益?

    众多工厂生产现状 1 设施设备先进 但是管理方式落后 手工管理模式的存在 造成数据的不准确和不完全 没有完全实现信息化管理 2 生产计划协调性差 作业调度困难 生产作业计划主要依据调度员的经验制定 设备利用率低 任务进度监控难 紧急插单普遍
  • C++虚基类

    问题引出 问题 A中数据 在D中保存了两份 虚继承 虚继承的目的是让某个类做出声明 承诺愿意共享它的基类 其中 这个被共享的基类就称为虚基类 Virtual Base Class 虚派生只影响从指定了虚基类的派生类中进一步派生出来的类 它不
  • 扎心!为何HR看了你的简历却不通知面试?

    还只是老老实实地写简历 投简历 默默地等待面试通知 那只有两种可能 你太天真 或者是 你真的很久没有 求职 了 如果你细心观察会发现 当你完成一份简历之后 它的状态也会有变化 然而 却有很多求职者并没有搞清楚这些 状态 到底代表着什么 但小
  • idea 配置 JavaWeb 项目的 tomcat

    目录 第一步 单击 idea 靠右上部位的 添加配置 Add Config Run Config 第二步 点击 添加新 或者图中箭头指向的任意一个地方 第三步 选择 Tomcat 服务器 本地 不是 TomEE 第四步 若以前从未配置 To
  • 使用SARIMA做季节时间序列预测全流程(附MATLAB代码)

    在之前的专栏中我们用ARIMA的方法做了时间序列的趋势性预测 不过我们经常还会遇到一种情况 即某些时间序列中存在明显的周期性变化 这种周期是由于季节性变化 季度 月度等 引起的 如下图所示 为1949年到1960年每月国际航空公司的乘客人数
  • C# pdf文件加数字证书,防篡改

    C 指定文件夹内新创建pdf文件加签数字证书 代码实现 引用 Spire Pdf string files Directory GetFiles Config pdfPath 需加数字证书pdf存放文件夹地址 string filesLis
  • 进程信号生命周期详解

    信号和信号量半毛钱关系都没有 每个信号都有一个编号和一个宏定义名称 这些宏定义可以在signal h中找到 例如其中有定 义 define SIGINT 2 查看信号的机制 如默认处理动作man 7 signal SIGINT的默认处理动作
  • c++自定义类型和预处理

    struct 内部初始化变量时 不能用 struct data int x 12 float f 122 5f int pi x data da cout lt lt da f lt lt endl data dap new data 使用
  • 配置 nginx 遇到错误排查(初级)

    系统版本 ubuntu 14 04 nginx 版本 nginx 1 4 6 Ubuntu 本文不是一步步搭建 nginx 的过程 而是我在使用 nginx 的过程中 整理自己遇到的的一些问题 适用于 nginx 遇到问题 排查问题的 ch
  • Neo4J 初次启动与密码

    初次安装成功Neo4J在安装的文件中会有一个bin文件夹 powershell进入bin文件夹执行 neo4j sonsole会有以下结果 D neo4j bin gt neo4j console 2020 09 04 00 57 31 0
  • Python基于PyTorch实现卷积神经网络分类模型(CNN分类算法)项目实战

    说明 这是一个机器学习实战项目 附带数据 代码 文档 视频讲解 如需数据 代码 文档 视频讲解可以直接到文章最后获取 1 项目背景 卷积神经网络 简称为卷积网络 与普通神经网络的区别是它的卷积层内的神经元只覆盖输入特征局部范围的单元 具有稀
  • oracle 9i在线重定义,在oracle 9i下在线重定义表

    9i提供了联机重定义表的方法 可以让你在基本不影响原表的DML情况下修改表结构 实际上 联机重定义表并不是完全的联机重定义 在最后交换表名的时候会短暂地锁定原表和中间表 但这个过程很短暂 相对于传统方法来说 这是一个进步 9i提供了联机重定
  • CNN、BiGRU、BiLSTM代码

    toxicCommentsclassification BiLSTMAttentionNetwork py at master AmritSatpathy toxicCommentsclassification GitHubtoxic co
  • BlueStore 架构及原理分析

    BlueStore 架构及原理分析 Ceph 底层存储引擎经过了数次变迁 目前最常用的是 BlueStore 在 Jewel 版本中引入 用来取代 FileStore 与 FileStore 相比 Bluesore 越过本地文件系统 直接操
  • 算法训练营第四十一天(9.2)

    Leecode 1143 最长公共子序列 题目地址 力扣 LeetCode 官网 全球极客挚爱的技术成长平台 题目类型 最长子序列 class Solution public int longestCommonSubsequence str
  • cython代码编译和setup.py文件编写

    Cython 官方文档 https cython readthedocs io en latest 中文文档 https www bookstack cn read cython doc zh https cython apachecn o