Python/OpenCL: Difference between revisions
< Python
Jump to navigation
Jump to search
No edit summary |
|||
| Line 13: | Line 13: | ||
|} | |} | ||
== | == Sample == | ||
<source lang="python3"> | <source lang="python3"> | ||
import os | import os | ||
| Line 20: | Line 20: | ||
# Kernel code. | # Kernel code. | ||
CL_INC = ''' | |||
__kernel void inc_f32(__global const float *a_g, __global float *res_g) | __kernel void inc_f32(__global const float *a_g, __global float *res_g) | ||
{ | |||
int gid = get_global_id(0); | |||
res_g[gid] = a_g[gid] + 1.0; | |||
} | |||
__kernel void inc_f64(__global const double *a_g, __global double *res_g) | |||
{ | |||
int gid = get_global_id(0); | |||
res_g[gid] = a_g[gid] + 1.0; | |||
} | |||
__kernel void inc_i32(__global const int *a_g, __global int *res_g) | |||
{ | |||
int gid = get_global_id(0); | |||
res_g[gid] = a_g[gid] + 1; | |||
} | |||
__kernel void inc_i64(__global const long *a_g, __global long *res_g) | |||
{ | { | ||
int gid = get_global_id(0); | int gid = get_global_id(0); | ||
| Line 28: | Line 46: | ||
''' | ''' | ||
# | # Build | ||
os.environ['PYOPENCL_CTX'] = '0:1' # Apple > HD Graphics 4000 of Macbook Air 2012 mid | os.environ['PYOPENCL_CTX'] = '0:1' # Apple > HD Graphics 4000 of Macbook Air 2012 mid | ||
ctx = cl.create_some_context() | ctx = cl.create_some_context() | ||
queue = cl.CommandQueue(ctx) | queue = cl.CommandQueue(ctx) | ||
mf = cl.mem_flags | |||
prg = cl.Program(ctx, CL_INC).build() | |||
# | # Shorthand to call kernel function. | ||
def call_kernel(kernel_name, *args): | |||
in_np = | in_np = args[0] | ||
in_cl = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=in_np) | out_np = np.empty_like(in_np) | ||
out_cl = cl.Buffer(ctx, mf.WRITE_ONLY, in_np.nbytes) | in_cl = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=in_np) | ||
out_cl = cl.Buffer(ctx, mf.WRITE_ONLY, in_np.nbytes) | |||
getattr(prg, kernel_name)(queue, in_np.shape, None, in_cl, out_cl) | |||
cl.enqueue_copy(queue, out_np, out_cl) | |||
return out_np | |||
# | # Test inc_f32() | ||
in_np = np.array([1.0, 2.0, 3.0, 4.0, 5.0]).astype(np.float32) | |||
out_np = call_kernel('inc_f32', in_np) | |||
print('Results of inc_f32()') | |||
print(in_np) | |||
print(out_np) | |||
print() | |||
# | # Test inc_f64() | ||
in_np = np.array([1.0, 2.0, 3.0, 4.0, 5.0]) | |||
out_np = call_kernel('inc_f64', in_np) | |||
print('Results of inc_f64()') | |||
print(in_np) | |||
print(out_np) | |||
print() | |||
# | # Test inc_i32() | ||
in_np = np.array([1, 2, 3, 4, 5]).astype(np.int32) | |||
out_np = call_kernel('inc_i32', in_np) | |||
print('Results of inc_i32()') | |||
print(in_np) | |||
print(out_np) | |||
print() | |||
# Test inc_i64() | |||
in_np = np.array([1, 2, 3, 4, 5]) | |||
out_np = call_kernel('inc_i64', in_np) | |||
print('Results of inc_i64()') | |||
print(in_np) | print(in_np) | ||
print(out_np) | print(out_np) | ||
print() | |||
</source> | </source> | ||
Revision as of 08:13, 6 June 2018
pyopencl
Type Mapping
| OpenCL | Numpy |
|---|---|
| float | np.float32 |
| double | np.float64 (default) |
| int | np.int32 |
| long | np.int64 (default) |
Sample
import os
import numpy as np
import pyopencl as cl
# Kernel code.
CL_INC = '''
__kernel void inc_f32(__global const float *a_g, __global float *res_g)
{
int gid = get_global_id(0);
res_g[gid] = a_g[gid] + 1.0;
}
__kernel void inc_f64(__global const double *a_g, __global double *res_g)
{
int gid = get_global_id(0);
res_g[gid] = a_g[gid] + 1.0;
}
__kernel void inc_i32(__global const int *a_g, __global int *res_g)
{
int gid = get_global_id(0);
res_g[gid] = a_g[gid] + 1;
}
__kernel void inc_i64(__global const long *a_g, __global long *res_g)
{
int gid = get_global_id(0);
res_g[gid] = a_g[gid] + 1;
}
'''
# Build
os.environ['PYOPENCL_CTX'] = '0:1' # Apple > HD Graphics 4000 of Macbook Air 2012 mid
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
mf = cl.mem_flags
prg = cl.Program(ctx, CL_INC).build()
# Shorthand to call kernel function.
def call_kernel(kernel_name, *args):
in_np = args[0]
out_np = np.empty_like(in_np)
in_cl = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=in_np)
out_cl = cl.Buffer(ctx, mf.WRITE_ONLY, in_np.nbytes)
getattr(prg, kernel_name)(queue, in_np.shape, None, in_cl, out_cl)
cl.enqueue_copy(queue, out_np, out_cl)
return out_np
# Test inc_f32()
in_np = np.array([1.0, 2.0, 3.0, 4.0, 5.0]).astype(np.float32)
out_np = call_kernel('inc_f32', in_np)
print('Results of inc_f32()')
print(in_np)
print(out_np)
print()
# Test inc_f64()
in_np = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
out_np = call_kernel('inc_f64', in_np)
print('Results of inc_f64()')
print(in_np)
print(out_np)
print()
# Test inc_i32()
in_np = np.array([1, 2, 3, 4, 5]).astype(np.int32)
out_np = call_kernel('inc_i32', in_np)
print('Results of inc_i32()')
print(in_np)
print(out_np)
print()
# Test inc_i64()
in_np = np.array([1, 2, 3, 4, 5])
out_np = call_kernel('inc_i64', in_np)
print('Results of inc_i64()')
print(in_np)
print(out_np)
print()
numpy
Data Types
import numpy as np
# Default int type is int64
a = np.array([1, 2, 3])
print(type(a[0]).__name__)
# Default float type is float64
b = np.array([1.0, 2.0, 3.0])
print(type(b[0]).__name__)
# Force int32
c = np.array([1, 2, 3]).astype(np.int32)
print(type(c[0]).__name__)
# Force float32
d = np.array([1.0, 2.0, 3.0]).astype(np.float32)
print(type(d[0]).__name__)