簡體   English   中英

將強制轉換錯誤'__Pyx_memviewslice'鍵入為'double *'Cython,這等效於什么? MKL函數prange代碼

[英]Type cast error '__Pyx_memviewslice' to 'double *' Cython, what's the equivalent? MKL function prange code

我編寫了一個Cython程序,調用Intel MKL進行矩陣乘法,目的是使其並行。 它基於鏈接到BLAS的舊SO帖子,並使用了許多我從未見過的Cython方法,但是使它起作用了,並且比NumPy(也鏈接到MKL)要慢得多。 為了加快速度,我使用了典型的Memoryview格式(它使用ndarray np.float64_t數據類型進行了幾次操作)。 但是現在使用double[::1] Memoryviews不再有效。 這是生成的錯誤: 'type cast': cannot convert from '__Pyx_memviewslice' to 'double *'

由於類型轉換不起作用,因此MKL函數僅看到5個參數中的3個: error C2660: 'cblas_ddot': function does not take 3 arguments

這是.PYX代碼:

import numpy as np
cimport numpy as np
cimport cython
from cython cimport view
from cython.parallel cimport prange     #this is your OpenMP portion
from openmp cimport omp_get_max_threads #only used for getting the max # of threads on the machine 

cdef extern from "mkl_cblas.h" nogil: #import a function from Intel's MKL library
    double ddot "cblas_ddot"(int N,
                             double *X, 
                             int incX,
                             double *Y, 
                             int incY)

@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
cpdef matmult(double[:,::1] A, double[:,::1] B):
    cdef int Ashape0=A.shape[0], Ashape1=A.shape[1], Bshape0=B.shape[0], Bshape1=B.shape[1], Arowshape0=A[0,:].shape[0] #these are defined here as they aren't allowed in a prange loop

    if Ashape1 != Bshape1:
        raise TypeError('Inner dimensions are not consistent!')

    cdef int i, j
    cdef double[:,::1] out = np.zeros((Ashape0, Bshape1))
    cdef double[::1] A_row = np.zeros(Ashape0)
    cdef double[:] B_col = np.zeros(Bshape1) #no idea why this is not allowed to be [::1]
    cdef int Arowstrides = A_row.strides[0] // sizeof(double)
    cdef int Bcolstrides = B_col.strides[0] // sizeof(double)
    cdef int maxthreads = omp_get_max_threads()

    for i in prange(Ashape0, nogil=True, num_threads=maxthreads, schedule='static'): # to use all cores

        A_row = A[i,:]
        for j in range(Bshape1):
            B_col = B[:,j]
            out[i,j] = ddot(Arowshape0, #call the imported Intel MKL library
                            <double*>A_row,
                            Arowstrides, 
                            <double*>B_col,
                            Bcolstrides) 

return np.asarray(out)

我確信這對SO人士來說很容易指出。 並且請告知您是否看到可以改進的地方-這已被黑客砍斷,我什至不需要i / j循環。 我周圍最干凈的示例: https : //gist.github.com/JonathanRaiman/f2ce5331750da7b2d4e9我最終編譯的實際上更快(2倍),但沒有結果,所以我將其放在另一篇文章中(此處: 直接調用BLAS / LAPACK)使用SciPy界面和Cython-以及如何添加MKL

非常感激。

要從memoryview獲取指針,您需要獲取第一個元素的地址

ddot(Arowshape0, #call the imported Intel MKL library
                        &A_row[0],
                        Arowstrides, 
                        &B_col[0],
                        Bcolstrides)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM