如何在 Numba 中使用指针包装 CFFI 函数

2024-01-14

这应该是一项简单的任务,但我找不到如何将标量值的指针传递给 Numba 函数内的 CFFI 函数的方法。使用以下命令将指针传递给数组可以毫无问题ffi.from_buffer.

示例函数

import cffi

ffi = cffi.FFI()
defs="void foo_f(int a,double *b);"
ffi.cdef(defs, override=True)
source="""
#include <stdio.h>;
void foo_f(int a,double *b){
  printf("%i",a);
  printf("   ");
  printf("%f",b[0]);
  }

"""
ffi.set_source(module_name="foo",source=source)
ffi.compile()

将指针传递给数组

import numpy as np
import numba as nb
import cffi
ffi = cffi.FFI()
import numpy as np
import ctypes
import foo
nb.cffi_support.register_module(foo)
foo_f = foo.lib.foo_f

@nb.njit()
def Test(a,b):
  a_wrap=np.int32(a)
  #This works for an array
  b_wrap=ffi.from_buffer(b.astype(np.float64))
  foo_f(a_wrap,b_wrap)


a=64.
b=np.ones(5)
Test(a,b)

这工作没有问题,但我该如何修改Test获取标量值的函数b=5.不修改 CFFI 函数本身?


使用 Numba 通过引用传递标量值

为了获得有用的计时,我对包装函数进行了一些修改。该函数只是将标量(按值传递)添加到标量 b(按引用传递)。

使用内在函数的方法的优点和缺点

  • 仅在 nopython 模式下工作
  • C 或 Fortran 函数速度更快,运行时间短(现实世界的例子 https://github.com/person142/numba_special/issues/1#issuecomment-568278201)

示例函数

import cffi

ffi = cffi.FFI()
defs="void foo_f(double a,double *b);"
ffi.cdef(defs, override=True)
source="""
void foo_f(double a,double *b){
  b[0]+=a;
  }
"""
ffi.set_source(module_name="foo",source=source)
ffi.compile()

使用临时数组的包装器

这非常简单,但需要分配一个大小为 1 的数组,这非常慢。

import numpy as np
import numba as nb
from numba import cffi_support
import cffi
ffi = cffi.FFI()
import foo

nb.cffi_support.register_module(foo)
foo_f = foo.lib.foo_f

@nb.njit("float64(float64,float64)")
def method_using_arrays(a,b):
    b_arr=np.empty(1,dtype=np.float64)
    b_arr[0]=b
    b_arr_ptr=b_wrap=ffi.from_buffer(b_arr)
    foo_f(a,b_arr_ptr)
    return b_arr[0]

使用内在函数的包装器

from numba import types
from numba.extending import intrinsic
from numba import cgutils

@intrinsic
def ptr_from_val(typingctx, data):
    def impl(context, builder, signature, args):
        ptr = cgutils.alloca_once_value(builder,args[0])
        return ptr
    sig = types.CPointer(data)(data)
    return sig, impl

@intrinsic
def val_from_ptr(typingctx, data):
    def impl(context, builder, signature, args):
        val = builder.load(args[0])
        return val
    sig = data.dtype(data)
    return sig, impl

@nb.njit("float64(float64,float64)")
def method_using_intrinsics(a,b):
    b_ptr=ptr_from_val(b)
    foo_f(a,b_ptr)
    return val_from_ptr(b_ptr)

Timings

#Just call the wrapped function a few times
@nb.njit()
def timing_method_using_intrinsics(a,b):
    for i in range(1000):
        b=method_using_intrinsics(a,b)
    return b

#Just call the wrapped function a few times
@nb.njit()
def timing_method_using_arrays(a,b):
    for i in range(1000):
        b=method_using_arrays(a,b)
    return b

a=1.
b=1.

%timeit timing_method_using_intrinsics(a,b)
#5.15 µs ± 33.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit timing_method_using_arrays(a,b)
#121 µs ± 601 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Numba 中使用指针包装 CFFI 函数 的相关文章

随机推荐

  • PhoneGap 地理定位在 iOS10 中被阻止

    我的 Phonegap 应用程序利用 Cordova 3 8 webviews W3C Geolocation API 然而 自从从 iOS 9 x 升级到 iOS 10 测试版 以来 使用 navigator geolocation ge
  • Laravel 5.7 电子邮件验证抛出 403

    我在我正在开发的 Laravel 5 7 项目中实现了电子邮件验证 我收到了电子邮件 但每当我单击确认按钮甚至电子邮件中提供的 URL 时 都会收到 403 禁止错误 我已经搜索了多种解决方案 但未能找到解决此问题的方法 指向此错误的唯一合
  • 编辑一个单元格时,Swift tableview 会更改随机单元格的值

    我有一个很长的文本字段列表 所以我使用 tableView 这就是屏 幕的样子 https i stack imgur com GqpHN png 当我在其中一个单元格的文本字段中插入一些文本并向下滚动时 其他一些单元格会获得相同的文本字段
  • 将文本/标签添加到 D3 力定向图中的链接上

    我一直在研究修改后的力定向图 并且在将文本 标签添加到链接上时遇到一些问题 其中链接与节点未正确对齐 如何修复它 如何向 SVG 文本元素添加事件侦听器 添加 on dblclick function d 就是不行 这是代码片段
  • 如何动态计算 UILabel 高度[重复]

    这个问题在这里已经有答案了 我有以下代码 label numberOfLines 0 allows label to have as many lines as needed label text some long text label
  • 基于 SSL 的 CFHTTP

    我正在尝试使用 ColdFusion 通过 SSL 从服务器检索文件CFHTTP标记没有成功 我们的环境是使用服务器配置的Linux 使用的密钥库位于cf root runtime jre lib security cacerts 我从目标
  • 如何在Flask中实现基于角色的访问控制?

    是否有任何积极维护的插件可以帮助我创建具有基于角色的访问控制的 Flask 应用程序 例如管理员角色 会计角色 人力资源角色 Flask User看起来不错 但这些讨论表明维护者已经走了 Flask Login needs Flask Se
  • lambda 捕获的生命周期

    给出以下程序 include
  • 找不到分段用户的资源 - 应用程序令牌

    我能够进行身份验证并获取应用程序令牌以使用 Microsoft Graph API 我已设置所有委派和管理权限来访问用户 我还使用图形浏览器来验证我需要什么权限 https developer microsoft com en us gra
  • IIS 7.5 自定义 404 错误页面不适用于 Web 根索引/默认

    我使用 IIS 7 5 创建了一个自定义 404 和 403 14 错误页面 如果未找到静态文件 该页面将显示数据库中的内容 换句话说 如果我浏览到http mysite com test http mysite com test 如果在该
  • 当应用程序运行时,如何在android中以编程方式关闭通知?

    我正在尝试开发一个android我正在其中实现聊天功能的应用程序 但当我收到消息时 它会发出通知声音 用户使用应用程序时如何停止通知以编程方式 private void ChatNotifications String uid String
  • 引导多选搜索从数据库获取值

    我正在使用引导多选 https davidstutz github io bootstrap multiselect 在我的项目中 在搜索中我试图通过以下方式获取数据库值ajax请求 但它没有附加 这是我的代码 example gettin
  • 如何解析包含多个文档的 YAML 文件?

    这是我的解析代码 import yaml def yaml as python val Convert YAML to dict try return yaml load all val except yaml YAMLError as e
  • Locust:如何让 Locust 运行特定的时间

    官方的蝗虫文档 http docs locust io en latest 讲述如何编写无限期运行的简单 Locust 任务 无法找到如何运行持续特定时间的负载 以便测试在指定的时间间隔后自动停止 我不需要从网络界面获得它 命令行 代码选项
  • Git:执行提交后,显示上次推送到每个远程的日期

    我想要一个简单的 git 提交后操作 打印上次将更改推送到每个远程的日期 这样做的动机是简单地提醒您的存储库可能会变得不同步 或者很好地提醒您将更改备份到远程裸存储库 这是否存在 如果没有关于如何做到这一点的快速建议 如果它不存在 我最初的
  • aurelia 中的自定义属性不起作用?

    我正在学习 Aurelia 的工作原理 并且正在尝试让一个简单的自定义属性正常工作 它所做的只是根据某些值的变化来改变 div 文本的颜色 我有一个 div 其中包含 high bind changeColor 在我的属性中我有 impor
  • 适合简单游戏的易于使用的 3D 图形引擎? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何在 Entity Framework 5 Code First 迁移中重命名数据库列而不丢失数据?

    我使用 EF 5 0 Code First 迁移成功运行了默认的 ASP NET MVC 4 模板 但是 当我更新模型属性名称时 EF 5 0 会删除相应的表列数据 是否可以在不以自动方式删除数据的情况下重命名表列 手动编辑迁移的Up和Do
  • 如何使用 EF6 删除 1,000 行?

    我正在使用实体框架 6 我有一个包含测试信息的表 称为 测试 我正在删除 通过首先获取测试列表 执行以下操作从该表中获取行 每个删除然后提交 var testList testService GetTests 1 userId ToList
  • 如何在 Numba 中使用指针包装 CFFI 函数

    这应该是一项简单的任务 但我找不到如何将标量值的指针传递给 Numba 函数内的 CFFI 函数的方法 使用以下命令将指针传递给数组可以毫无问题ffi from buffer 示例函数 import cffi ffi cffi FFI de