Python/OpenCL

From Fundamental Ramen
Jump to navigation Jump to search

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__)