<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 1.8。使用`@cfunc` 創建 C 回調 > 原文: [http://numba.pydata.org/numba-doc/latest/user/cfunc.html](http://numba.pydata.org/numba-doc/latest/user/cfunc.html) 與某些本機庫(例如,用 C 或 C ++編寫)連接可能需要編寫本機回調以向庫提供業務邏輯。 [`numba.cfunc()`](../reference/jit-compilation.html#numba.cfunc "numba.cfunc") 裝飾器使用您選擇的簽名創建可從外部 C 代碼調用的編譯函數。 ## 1.8.1。基本用法 `@cfunc`裝飾器與`@jit`具有相似的用法,但有一個重要區別:傳遞單個簽名是強制性的。它確定 C 回調的可見簽名: ```py from numba import cfunc @cfunc("float64(float64, float64)") def add(x, y): return x + y ``` C 函數對象將已編譯的 C 回調的地址公開為 [`address`](../reference/jit-compilation.html#CFunc.address "CFunc.address") 屬性,以便您可以將其傳遞給任何外部 C 或 C ++庫。它還暴露了指向該回調的 [`ctypes`](https://docs.python.org/3/library/ctypes.html#module-ctypes "(in Python v3.7)") 回調對象;該對象也可以從 Python 調用,從而可以輕松檢查已編譯的代碼: ```py @cfunc("float64(float64, float64)") def add(x, y): return x + y print(add.ctypes(4.0, 5.0)) # prints "9.0" ``` ## 1.8.2。示例 在這個例子中,我們將使用`scipy.integrate.quad`函數。該函數接受常規 Python 回調或包含在 [`ctypes`](https://docs.python.org/3/library/ctypes.html#module-ctypes "(in Python v3.7)") 回調對象中的 C 回調。 讓我們定義一個純 Python 的 integrand 并將其編譯為 C 回調: ```py >>> import numpy as np >>> from numba import cfunc >>> def integrand(t): return np.exp(-t) / t**2 ...: >>> nb_integrand = cfunc("float64(float64)")(integrand) ``` 我們可以將`nb_integrand`對象的 [`ctypes`](https://docs.python.org/3/library/ctypes.html#module-ctypes "(in Python v3.7)") 回調傳遞給`scipy.integrate.quad`,并檢查結果是否與純 Python 函數相同: ```py >>> import scipy.integrate as si >>> def do_integrate(func): """ Integrate the given function from 1.0 to +inf. """ return si.quad(func, 1, np.inf) ...: >>> do_integrate(integrand) (0.14849550677592208, 3.8736750296130505e-10) >>> do_integrate(nb_integrand.ctypes) (0.14849550677592208, 3.8736750296130505e-10) ``` 使用已編譯的回調,集成函數在每次評估被積函數時都不會調用 Python 解釋器。在我們的例子中,集成速度提高了 18 倍: ```py >>> %timeit do_integrate(integrand) 1000 loops, best of 3: 242 μs per loop >>> %timeit do_integrate(nb_integrand.ctypes) 100000 loops, best of 3: 13.5 μs per loop ``` ## 1.8.3。處理指針和數組內存 C 回調的一個不太重要的用例涉及對調用者傳遞的某些數據數組進行操作。由于 C 沒有類似于 Numpy 數組的高級抽象,C 回調的簽名將傳遞低級指針和大小參數。然而,回調的 Python 代碼將期望利用 Numpy 數組的強大功能和表現力。 在下面的示例中,C 回調預計將在 2-d 數組上運行,簽名為`void(double *input, double *output, int m, int n)`。你可以這樣實現這樣的回調: ```py from numba import cfunc, types, carray c_sig = types.void(types.CPointer(types.double), types.CPointer(types.double), types.intc, types.intc) @cfunc(c_sig) def my_callback(in_, out, m, n): in_array = carray(in_, (m, n)) out_array = carray(out, (m, n)) for i in range(m): for j in range(n): out_array[i, j] = 2 * in_array[i, j] ``` [`numba.carray()`](../reference/utils.html#numba.carray "numba.carray") 函數將數據指針和形狀作為輸入,并返回給定形狀的數組視圖。假設數據按 C 順序排列。如果數據以 Fortran 順序排列,則應使用 [`numba.farray()`](../reference/utils.html#numba.farray "numba.farray") 。 ## 1.8.4。處理 C 結構 ### 1.8.4.1。用 CFFI 對于具有大量狀態的應用程序,在 C 結構中傳遞數據很有用。為了簡化與 C 代碼的互操作性,numba 可以使用`numba.cffi_support.map_type`將`cffi`類型轉換為 numba `Record`類型: ```py from numba import cffi_support nbtype = cffi_support.map_type(cffi_type, use_record_dtype=True) ``` 注意 **use_record_dtype = True** 是必需的,否則指向 C 結構的指針將作為 void 指針返回。 例如: ```py from cffi import FFI src = """ /* Define the C struct */ typedef struct my_struct { int i1; float f2; double d3; float af4[7]; // arrays are supported } my_struct; /* Define a callback function */ typedef double (*my_func)(my_struct*, size_t); """ ffi = FFI() ffi.cdef(src) # Get the function signature from *my_func* sig = cffi_support.map_type(ffi.typeof('my_func'), use_record_dtype=True) # Make the cfunc from numba import cfunc, carray @cfunc(sig) def foo(ptr, n): base = carray(ptr, n) # view pointer as an array of my_struct tmp = 0 for i in range(n): tmp += base[i].i1 * base[i].f2 / base[i].d3 tmp += base[i].af4.sum() # nested arrays are like normal numpy array return tmp ``` ### 1.8.4.2。用`numba.types.Record.make_c_struct` 可以手動創建`numba.types.Record`類型以遵循 C 結構的布局。為此,請使用`Record.make_c_struct`,例如: ```py my_struct = types.Record.make_c_struct([ # Provides a sequence of 2-tuples i.e. (name:str, type:Type) ('i1', types.int32), ('f2', types.float32), ('d3', types.float64), ('af4', types.NestedArray(dtype=types.float32, shape=(7,))), ]) ``` 由于 ABI 限制,應使用`types.CPointer(my_struct)`作為參數類型將結構作為指針傳遞。在`cfunc`體內,可以使用`carray`訪問`my_struct*`。 ### 1.8.4.3。完整示例 請參閱`examples/notebooks/Accessing C Struct Data.ipynb`中的完整示例。 ## 1.8.5。簽名規范 顯式`@cfunc`簽名可以使用任何 [Numba 類型](../reference/types.html#numba-types),但只有它們的一個子集對 C 回調有意義。您通常應將自己限制為標量類型(例如`int8`或`float64`),指向它們的指針(例如`types.CPointer(types.int8)`)或指向`Record`類型的指針。 ## 1.8.6。編譯選項 可以將許多僅關鍵字參數傳遞給`@cfunc`裝飾器:`nopython`和`cache`。它們的含義類似于`@jit`裝飾器中的含義。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看