import pyopencl as cl
import numpy as np

def load_binary_from_file(file_path, ctx):
    with open(file_path, "rb") as f:
        binary = f.read()
    return binary

def main():
    # Choose platform and create context
    platform = cl.get_platforms()[0]  # Select the first platform
    device = platform.get_devices()[0]  # Select the first device on this platform
    context = cl.Context([device])  # Create a context with the above device

    # Load binary file
    binary_path = "kernel.aocx"  # Path to your binary file
    binary = load_binary_from_file(binary_path, context)

    # Create program from binary
    program = cl.Program(context, [device], [binary]).build()

    # Prepare data and buffers
    size = 1024
    a_np = np.random.rand(size).astype(np.float32)
    b_np = np.random.rand(size).astype(np.float32)

    # Create memory buffers
    mf = cl.mem_flags
    a_g = cl.Buffer(context, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=a_np)
    b_g = cl.Buffer(context, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=b_np)
    res_g = cl.Buffer(context, mf.WRITE_ONLY, a_np.nbytes)

    # Create a command queue
    queue = cl.CommandQueue(context)

    # Execute the kernel
    kernel = program.vector_add  # Replace 'kernel_name' with your kernel's function name
    kernel(queue, a_np.shape, None, a_g, b_g, res_g)

    # Read the result
    res_np = np.empty_like(a_np)
    cl.enqueue_copy(queue, res_np, res_g).wait()

    print("Result:", res_np)

if __name__ == "__main__":
    main()

