2

How should I apply defined function to cupy.array instead of np.vectorize? Has similar function implemented yet in cupy?

I'm writing simulation program in Python 3.6.9.

I'd like to do the simulation in GPU(GTX1060, NVIDIA) with CuPy(6.0.0 for CUDA10.1).

In original code, function numpy.vectorize has used for apply defined function to np.array. However, same function has not implemented yet in CuPy.

Original code (using numpy) is as below:

#For define function
def rate(tmean,x,y,z):
    rate = 1/z/(1 + math.exp(-x*(tmean-y)))
    #DVR<0
    if rate < 0:
        rate = 0
    return rate

#tmean is temperature data(365,100,100) and loaded as np.array
#paras is parameter(3,100,100)
#vectorized
f = np.vectorize(rate)
#roop
for i in range(365):
    #calc developing rate(by function "rate") and accumulate
    dvi[i,:,:] = dvi[i-1,:,:] + f(tmean[i,:,:],paras[0],paras[1],paras[2])

I know almost functions of numpy has implemented in CuPy. so I changed

f = np.vectorized(rate) 

to

f= cp.vectorized(rate)

but AttributeError occurred.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
mas
  • 35
  • 7

1 Answers1

2

GPU cannot parallelize an arbitrary Python code. Write everything in NumPy-compatible operations like

def rate_(xp, tmean,x,y,z):
    rate = 1/z/(1 + xp.exp(-x*(tmean-y)))
    rate[rate < 0] = 0
    return rate

f = functools.partial(rate_, xp=cupy)

To speed up, you may use cupy.ElementwiseKernel (https://docs-cupy.chainer.org/en/stable/tutorial/kernel.html), which creates a single kernel for the vectorized operation.

f = cupy.ElementwiseKernel(
    'T tmean, T x, T y, T z',
    'T rate',
    '''
    rate = 1/z/(1 + exp(-x*(tmean-y)));
    // DVR<0
    if (rate < 0) {
        rate = 0;
    }
    '''
)

To create a kernel from a Python code, try cupy.fuse.

@cupy.fuse()
def f(tmean,x,y,z):
    rate = 1/z/(1 + cupy.exp(-x*(tmean-y)))
    return cupy.where(rate < 0, 0, rate)  # __setitem__ is not fully supported
tos
  • 281
  • 1
  • 3