Khalif21 Khalif21 - 1 month ago 10
Python Question

Python - How to pass Structures of array to function on shared file

I have researched for hours,


  1. How to access data from pointer in struct from Python with ctypes?

  2. Using Python Ctypes to pass struct pointer to a DLL function

  3. Convert C array of pointers to Python array of structures

  4. etc,



but I have not resolved my problem.

File: test.cu

extern TEST_API int fft_coba1d(cplx in, cplx outfft, cplx outdft, cplx outfftc, unsigned int size) // int argc, char **argv
{
....
checkCudaErrors(cudaHostAlloc((void**) &in.x, nBytes, cudaHostAllocDefault));
checkCudaErrors(cudaHostAlloc((void**) &in.y, nBytes, cudaHostAllocDefault));

checkCudaErrors(cudaHostAlloc((void**) &outfft.x, nBytes, cudaHostAllocDefault));
checkCudaErrors(cudaHostAlloc((void**) &outfft.y, nBytes, cudaHostAllocDefault));

checkCudaErrors(cudaHostAlloc((void**) &outdft.x, nBytes, cudaHostAllocDefault));
checkCudaErrors(cudaHostAlloc((void**) &outdft.y, nBytes, cudaHostAllocDefault));

checkCudaErrors(cudaHostAlloc((void**) &outfftc.x, nBytes, cudaHostAllocDefault));
checkCudaErrors(cudaHostAlloc((void**) &outfftc.y, nBytes, cudaHostAllocDefault));

....

checkCudaErrors(cudaFreeHost(outfft.x));
checkCudaErrors(cudaFreeHost(outfft.y));
checkCudaErrors(cudaFreeHost(outfftc.x));
checkCudaErrors(cudaFreeHost(outfftc.y));
checkCudaErrors(cudaFreeHost(outdft.x));
checkCudaErrors(cudaFreeHost(outdft.y));
}


File: test.h

#define DLL_FILE
#define EXPORT_FUNC
#ifdef DLL_FILE
#ifdef EXPORT_FUNC
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif
#else
#define TEST_API extern
#endif

#ifdef __cplusplus
extern "C" {
#endif


typedef struct
{
float* x;
float* y;
}cplx;
....
extern TEST_API int fft_coba1d(cplx in, cplx outfft, cplx outdft, cplx outfftc, unsigned int size);

#ifdef __cplusplus
}
#endif


File: test.py

import numpy as np
import ctypes
from ctypes import *
import matplotlib.pyplot as plt

class cplx(Structure):
_fields_ = [("x", POINTER(c_float)),
("y", POINTER(c_float))]

def get_cuda_fft():
dll = ctypes.CDLL('fftcoba.dll')#, mode=ctypes.RTLD_GLOBAL)
func = dll.fft_coba1d
func.argtypes = [cplx, cplx, cplx, cplx, c_uint]
func.restype = c_int
return func

__cuda_fft = get_cuda_fft()

def cuda_fft(a, b, c, d, size):
__cuda_fft(a, b, c, d, size)

if __name__ == '__main__':
size=8
size = int(size)
print size

in_ = cplx()
outfft = cplx()
outdft = cplx()
outfftc = cplx()
in_.x = (c_float * size)(np.array(size, dtype=float))
in_.y = (c_float * size)(np.array(size, dtype=float))

outfft.x = (c_float * size)(np.array(size, dtype=float))
outfft.y = (c_float * size)(np.array(size, dtype=float))

outdft.x = (c_float * size)(np.array(size, dtype=float))
outdft.y = (c_float * size)(np.array(size, dtype=float))

outfftc.x = (c_float * size)(np.array(size, dtype=float))
outfftc.y = (c_float * size)(np.array(size, dtype=float))

cuda_fft(in_, outfft, outdft, outfftc , size)

print in_[:4]


I get this error,
Python Stopped Working

How to Pass Structure of array on function that linked to shared library (dll file)?

How to get result from function on shared library?

Answer

I have solved my problem,

File Test.py

import numpy as np
import numpy.ctypeslib as npct
import ctypes
from ctypes import *
import matplotlib.pyplot as plt
import sys
import time


class cplx(Structure):
    _fields_ = [("x", ctypes.POINTER(c_float)),
                ("y", ctypes.POINTER(c_float))]              

# extract cuda_sum function pointer in the shared object cuda_sum.so
#
def get_cuda_fft():
    dll = ctypes.CDLL('fftcoba.dll')#, mode=ctypes.RTLD_GLOBAL)


    func = dll.fft_coba1d

    func.argtypes = [cplx, cplx, cplx, cplx, cplx ,c_int]                    
    func.restype = None
    return func

# create __cuda_sum function with get_cuda_sum()
__cuda_fft = get_cuda_fft()

# convenient python wrapper for __cuda_sum
# it does all job with types convertation
# from python ones to C++ ones 
def cuda_fft(in_, offt, odft, offtc, ocufft, size):
    __cuda_fft(in_, offt, odft, offtc, ocufft, size)

# testing, sum of two arrays of ones and output head part of resulting array
if __name__ == '__main__':
    size=sys.argv[1]
    size = int(size)

    p = 1
    while (size>p):
        p *= 2

    if size != p:
        size = p

    s1=time.clock()
    IN = cplx()
    outDFT = cplx()
    outFFT = cplx()
    outFFTC = cplx()
    outCUFFT = cplx()



    IN.x = (c_float * size)(np.array(size,dtype=c_float))
    IN.y = (c_float * size)(np.array(size,dtype=c_float))
    outDFT.x = (c_float * size)(np.array(size,dtype=c_float))
    outDFT.y = (c_float * size)(np.array(size,dtype=c_float))
    outFFT.x = (c_float * size)(np.array(size,dtype=c_float))
    outFFT.y = (c_float * size)(np.array(size,dtype=c_float))
    outFFTC.x = (c_float * size)(np.array(size,dtype=c_float))
    outFFTC.y = (c_float * size)(np.array(size,dtype=c_float))
    outCUFFT.x = (c_float * size)(np.array(size,dtype=c_float))
    outCUFFT.y = (c_float * size)(np.array(size,dtype=c_float))


    # print type(Inputx)
    # print Inputx.shape
    i = np.linspace(0,size-1, size)
    f1 = time.clock()
    print 'Exection Time for initializing Data : ', f1-s1, 'Second'

    s2 = time.clock()
    # size = ctypes.sc_uint(size)
    cuda_fft(IN, outFFT, outDFT, outFFTC, outCUFFT, size)
    f2 = time.clock()
    print 'Execution Time for Cuda FFT : ', f2-s2, ' Seconds'

    print 'From Output FFT Method ?'
    print outFFT.x[3]


    s3 = time.clock()
 # ///////////////////////////////////////////////////////////////////METHOD COPY DATA C_FLOAT POINTER TO NP>FLOAT//////////////////////////////////////////////    
    Inputx = npct.as_array(IN.x, shape=(size,))
    Inputy = npct.as_array(IN.y, shape=(size,))
    outfftx = npct.as_array(outFFT.x, shape=(size,))
    outdftx = npct.as_array(outDFT.x, shape=(size,))
    outfftcx = npct.as_array(outFFTC.x, shape=(size,))
    outcufftx = npct.as_array(outCUFFT.x, shape=(size,))

    # ///////////////////////////////////////////////////////////////////METHOD COPY DATA C_FLOAT POINTER TO NP>FLOAT//////////////////////////////////////////////

    for i in range(size):
        Inputx[i] = IN.x[i]
        Inputy[i] = IN.y[i]
        outfftx[i] = outFFT.x[i]
        outdftx[i] = outDFT.x[i]
        outfftcx[i] = outFFTC.x[i]
        outcufftx[i] = outCUFFT.x[i]

    i = np.linspace(0,size-1, size)
    print type(Inputx)
    # print Inputx.shape[0]
    print i.shape
    f3 = time.clock()
    print 'Execution Time for Copying Data to array Python is ', f3-s3, 'Seconds'

    plt.subplot(511)
    plt.plot(i,Inputx)
    plt.xlabel('X-Axis')
    plt.ylabel('Y-Axis')
    plt.title("Input",color='r')

    plt.subplot(512)
    plt.plot(i,outfftx)
    plt.xlabel('X-Axis')
    plt.ylabel('Y-Axis')
    plt.title("FFT CPU",color='r')

    plt.subplot(513)
    plt.plot(i,outdftx)
    plt.xlabel('X-Axis')
    plt.ylabel('Y-Axis')
    plt.title("DFT CPU",color='r')

    plt.subplot(514)
    plt.plot(i,outfftcx)
    plt.xlabel('X-Axis')
    plt.ylabel('Y-Axis')
    plt.title("FFT CUDA",color='r')

    plt.subplot(515)
    plt.plot(i,outcufftx)
    plt.xlabel('X-Axis')
    plt.ylabel('Y-Axis')
    plt.title("CUFFT CUDA",color='r')

    plt.show()

    del Inputy
    del outfftx
    del outdftx
    del outfftcx
    del outcufftx

file test.h

typedef struct  
{
    float* x;
    float* y;
}cplx;     

extern RIZ_API void fft_coba1d(cplx in, 
                            cplx outfft,  
                            cplx outdft, 
                            cplx outfftc, 
                            cplx ocufft, 
                                 int size); // int argc, char **argv
Comments