Search code examples
pythonopenclpyopencl

OpenCL mapping input to output


I have an input [1,2,3,4,1,3,3,5,1,2,5,4,1,3] of size 14, and I use it as a Kernel input. This input is to be copied to the output buffer starting from a given output buffer index. This work is to happen at a single workitem location (for experimental purposes). I then print out my mapping results using the format (input_int --> work_item_id --> output_int)and the copied output. The mapping shows that all the input string (size 14) has been mapped to output but the copied output only prints 7 slots as Resulting output in the results image. 7 is the number of workitems but I intended to copy the entire input to output at workitem 0. What is happening here?

The program:

#!/usr/bin/env python3
#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable
 #pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable
import pyopencl as cl
import numpy as np
import seq

# Write down our kernel as a multiline string.
kernel = """
    __kernel void dragon(
    const int N,
    __global char *AplusB,   

    __global char *output
    )
{   
    int idx = get_global_id(0); 


        if(idx == 0){ //A+B
           printf ("\\n mappings from input to output in kernel at idx %d",idx);  
            for (int i = 0; i <14; i++){
                     output[i]= AplusB[i];
                     int a = output[i];
                     int b =AplusB[i]; 

                     printf("\\n %d --> %d --> %d \\n",b,idx, a);
            }
        }
   }
"""
#declare constants
number_of_expansions = 4
total_probelem_size =7
resulting_str_size=62

# Step 1: Create a context.
# This will ask the user to select the device to be used.
context = cl.create_some_context()
# Create a queue to the device.
queue = cl.CommandQueue(context)
# Create the program.
program = cl.Program(context, kernel).build()
# Create the input string
AplusB  = np.array([1,2,3,4,1,3,3,5,1,2,5,4,1,3], dtype = np.int8)


#prepare out buffers
output = np.empty(total_probelem_size).astype(np.int8)
output.fill(0)

 # Create the memory on the device to put the result into.
expanded_output = cl.Buffer(context, cl.mem_flags.WRITE_ONLY, output.nbytes)


# Send the data to the guest memory.

mf = cl.mem_flags
AplusBBuf = cl.Buffer(context, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=AplusB)



# Initiate the kernel.
dragon = program.dragon
dragon.set_scalar_arg_dtypes([np.int32, None,None])

global_work_size = total_probelem_size
# Execute C = A * B.
dragon(queue, (global_work_size,), None,total_probelem_size,AplusBBuf,expanded_output)
# Wait for the queue to be completely processed.
queue.finish()
# Read the array from the device.

cl.enqueue_copy(queue, output, expanded_output).wait()
print("----------- Resulting output -------------------")
print (output)

Results: enter image description here


Solution

  • expanded_output and output are allocated with a size of 7 elements (total_probelem_size). Thus the kernel writing to output[i=7] to output[i=13] writes to invalid memory locations.

    As the output array only contains 7 elements, only 7 elements are printed.