//
// Copyright (c) 2017 The Khronos Group Inc.
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "harness/compat.h"

#include <assert.h>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <sys/stat.h>
#include <sys/types.h>

#include "procs.h"
#include "harness/errorHelpers.h"

#define STRING_LENGTH  1024

void createKernelSourceCode(std::stringstream &stream, int num_pipes)
{
    int i;

    stream << "__kernel void test_multiple_pipe_write(__global int *src, ";
    for (i = 0; i < num_pipes; i++)
    {
        stream << "__write_only pipe int pipe" << i << ", ";
    }
    stream << R"(int num_pipes )
    {
          int gid = get_global_id(0);
          reserve_id_t res_id;


          if(gid < (get_global_size(0))/num_pipes)
          {
                 res_id = reserve_write_pipe(pipe0, 1);
                 if(is_valid_reserve_id(res_id))
                 {
                     write_pipe(pipe0, res_id, 0, &src[gid]);
                     commit_write_pipe(pipe0, res_id);
                 }
          })";

    for (i = 1; i < num_pipes; i++)
    {
        // clang-format off
        stream << R"(
          else if(gid < ()" << (i + 1) << R"(*get_global_size(0))/num_pipes)
          {
                 res_id = reserve_write_pipe(pipe)" << i << R"(, 1);
                 if(is_valid_reserve_id(res_id))
                 {
                     write_pipe(pipe)" << i << R"(, res_id, 0, &src[gid]);
                     commit_write_pipe(pipe)" << i << R"(, res_id);
                  }
          }
          )";
          // clang-format om
    }
    stream << R"(
    }

    __kernel void test_multiple_pipe_read(__global int *dst, )";

    for (i = 0; i < num_pipes; i++)
    {
        stream << "__read_only pipe int pipe" << i << ", ";
    }
    stream << R"(int num_pipes )
    {
            int gid = get_global_id(0);
            reserve_id_t res_id;


            if(gid < (get_global_size(0))/num_pipes)
            {
                res_id = reserve_read_pipe(pipe0, 1);
                if(is_valid_reserve_id(res_id))
                {
                    read_pipe(pipe0, res_id, 0, &dst[gid]);
                    commit_read_pipe(pipe0, res_id);
                }
            })";

    for (i = 1; i < num_pipes; i++)
    {
        // clang-format off
        stream << R"(
            else if(gid < ()"    << (i + 1) << R"(*get_global_size(0))/num_pipes)
            {
                res_id = reserve_read_pipe(pipe)" << i << R"(, 1);
                if(is_valid_reserve_id(res_id))
                {
                    read_pipe(pipe)" << i << R"(, res_id, 0, &dst[gid]);
                    commit_read_pipe(pipe)" << i << R"(, res_id);
                }
            })";
        // clang-format on
    }
    stream << "}";
}

static int verify_result(void *ptr1, void *ptr2, int n)
{
    int     i;
    int        sum_input = 0, sum_output = 0;
    cl_char    *inptr = (cl_char *)ptr1;
    cl_char    *outptr = (cl_char *)ptr2;

    for(i = 0; i < n; i++)
    {
        sum_input += inptr[i];
        sum_output += outptr[i];
    }
    if(sum_input != sum_output){
        return -1;
    }
    return 0;
}

static int verify_result_int(void *ptr1, void *ptr2, int n)
{
    int     i;
    int        sum_input = 0, sum_output = 0;
    cl_int    *inptr = (cl_int *)ptr1;
    cl_int    *outptr = (cl_int *)ptr2;

    for(i = 0; i < n; i++)
    {
        sum_input += inptr[i];
        sum_output += outptr[i];
    }
    if(sum_input != sum_output){
        return -1;
    }
    return 0;
}

int test_pipe_max_args(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{

    clMemWrapper pipes[1024];
    clMemWrapper buffers[2];
    void *outptr;
    cl_int *inptr;
    clProgramWrapper program;
    clKernelWrapper kernel[2];
    size_t global_work_size[3];
    cl_int err;
    cl_int size;
    int num_pipe_elements = 1024;
    int i, j;
    int max_pipe_args;
    std::stringstream source;
    clEventWrapper producer_sync_event = NULL;
    clEventWrapper consumer_sync_event = NULL;
    BufferOwningPtr<cl_int> BufferInPtr;
    BufferOwningPtr<cl_int> BufferOutPtr;

    MTdataHolder d(gRandomSeed);
    const char *kernelName[] = { "test_multiple_pipe_write",
                                 "test_multiple_pipe_read" };

    size_t min_alignment = get_min_alignment(context);

    err = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_PIPE_ARGS,
                          sizeof(max_pipe_args), (void *)&max_pipe_args, NULL);
    if (err)
    {
        print_error(err, " clGetDeviceInfo failed\n");
        return -1;
    }
    if(max_pipe_args < 16){
        log_error("The device should support minimum 16 pipe objects that could be passed as arguments to the kernel");
        return -1;
    }

    global_work_size[0] = (cl_uint)num_pipe_elements * max_pipe_args;
    size = sizeof(int) * num_pipe_elements * max_pipe_args;

    inptr = (cl_int *)align_malloc(size, min_alignment);

    for(i = 0; i < num_pipe_elements * max_pipe_args; i++){
        inptr[i] = (int)genrand_int32(d);
    }
    BufferInPtr.reset(inptr, nullptr, 0, size, true);

    buffers[0] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, size, inptr, &err);
    test_error_ret(err, " clCreateBuffer failed", -1);

    outptr = align_malloc(size, min_alignment);
    BufferOutPtr.reset(outptr, nullptr, 0, size, true);
    buffers[1] = clCreateBuffer(context, CL_MEM_USE_HOST_PTR,  size, outptr, &err);
    test_error_ret(err, " clCreateBuffer failed", -1);

    for(i = 0; i < max_pipe_args; i++){
        pipes[i] = clCreatePipe(context, CL_MEM_HOST_NO_ACCESS, sizeof(int), num_pipe_elements, NULL, &err);
        test_error_ret(err, " clCreatePipe failed", -1);
    }

    createKernelSourceCode(source, max_pipe_args);

    std::string kernel_source = source.str();
    const char *sources[] = { kernel_source.c_str() };

    // Create producer kernel
    err = create_single_kernel_helper_with_build_options(
        context, &program, &kernel[0], 1, sources, kernelName[0],
        "-cl-std=CL2.0");
    test_error_ret(err, " Error creating program", -1);

    //Create consumer kernel
    kernel[1] = clCreateKernel(program, kernelName[1], &err);
    test_error_ret(err, " Error creating kernel", -1);

    err = clSetKernelArg(kernel[0], 0, sizeof(cl_mem), (void*)&buffers[0]);
    for( i = 0; i < max_pipe_args; i++){
        err |= clSetKernelArg(kernel[0], i+1, sizeof(cl_mem), (void*)&pipes[i]);
    }
    err |= clSetKernelArg(kernel[0], max_pipe_args + 1, sizeof(int), (void*)&max_pipe_args);
    err |= clSetKernelArg(kernel[1], 0, sizeof(cl_mem), (void*)&buffers[1]);
    for( i = 0; i < max_pipe_args; i++){
        err |= clSetKernelArg(kernel[1], i+1, sizeof(cl_mem), (void*)&pipes[i]);
    }
    err |= clSetKernelArg(kernel[1], max_pipe_args + 1, sizeof(int), (void*)&max_pipe_args);
    test_error_ret(err, " clSetKernelArg failed", -1);

    // Launch Producer kernel
    err = clEnqueueNDRangeKernel( queue, kernel[0], 1, NULL, global_work_size, NULL, 0, NULL, &producer_sync_event );
    test_error_ret(err, " clEnqueueNDRangeKernel failed", -1);

    // Launch Consumer kernel
    err = clEnqueueNDRangeKernel( queue, kernel[1], 1, NULL, global_work_size, NULL, 1, &producer_sync_event, &consumer_sync_event );
    test_error_ret(err, " clEnqueueNDRangeKernel failed", -1);

    err = clEnqueueReadBuffer(queue, buffers[1], true, 0, size, outptr, 1, &consumer_sync_event, NULL);
    test_error_ret(err, " clEnqueueNDRangeKernel failed", -1);

    err = clWaitForEvents(1, &consumer_sync_event);
    test_error_ret(err, " clWaitForEvents failed", -1);

    if( verify_result( inptr, outptr, num_pipe_elements*sizeof(cl_int))){
        log_error("test_pipe_max_args failed\n");
    }
    else {
        log_info("test_pipe_max_args passed\n");
    }

    return 0;
}


int test_pipe_max_packet_size(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
    clMemWrapper pipe;
    clMemWrapper buffers[2];
    void *outptr;
    cl_char *inptr;
    clProgramWrapper program;
    clKernelWrapper kernel[2];
    size_t global_work_size[3];
    cl_int err;
    size_t size;
    int num_pipe_elements = 1024;
    int i;
    cl_uint max_pipe_packet_size;
    clEventWrapper producer_sync_event = NULL;
    clEventWrapper consumer_sync_event = NULL;
    BufferOwningPtr<cl_int> BufferInPtr;
    BufferOwningPtr<cl_int> BufferOutPtr;
    MTdataHolder d(gRandomSeed);
    const char *kernelName[] = { "test_pipe_max_packet_size_write",
                                 "test_pipe_max_packet_size_read" };

    size_t min_alignment = get_min_alignment(context);

    global_work_size[0] = (cl_uint)num_pipe_elements;

    std::stringstream source;

    err = clGetDeviceInfo(deviceID, CL_DEVICE_PIPE_MAX_PACKET_SIZE,
                          sizeof(max_pipe_packet_size),
                          (void *)&max_pipe_packet_size, NULL);
    test_error_ret(err, " clCreatePipe failed", -1);

    if (max_pipe_packet_size < 1024)
    {
        log_error(
            "The device should support minimum packet size of 1024 bytes");
        return -1;
    }

    if(max_pipe_packet_size > (32*1024*1024/num_pipe_elements))
    {
        max_pipe_packet_size = 32*1024*1024/num_pipe_elements;
    }

    size = max_pipe_packet_size * num_pipe_elements;

    inptr = (cl_char *)align_malloc(size, min_alignment);

    for(i = 0; i < size; i++){
        inptr[i] = (char)genrand_int32(d);
    }
    BufferInPtr.reset(inptr, nullptr, 0, size, true);

    buffers[0] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, size, inptr, &err);
    test_error_ret(err, " clCreateBuffer failed", -1);

    outptr = align_malloc(size, min_alignment);
    BufferOutPtr.reset(outptr, nullptr, 0, size, true);

    buffers[1] = clCreateBuffer(context, CL_MEM_USE_HOST_PTR,  size, outptr, &err);
    test_error_ret(err, " clCreateBuffer failed", -1);

    pipe = clCreatePipe(context, CL_MEM_HOST_NO_ACCESS, max_pipe_packet_size, num_pipe_elements, NULL, &err);
    test_error_ret(err, " clCreatePipe failed", -1);

    // clang-format off
    source << R"(
        typedef struct{
            char a[)" << max_pipe_packet_size << R"(];
        }TestStruct;

        __kernel void test_pipe_max_packet_size_write(__global TestStruct *src, __write_only pipe TestStruct out_pipe)
        {
            int gid = get_global_id(0);
            reserve_id_t res_id;

            res_id = reserve_write_pipe(out_pipe, 1);
            if(is_valid_reserve_id(res_id))
            {
                write_pipe(out_pipe, res_id, 0, &src[gid]);
                commit_write_pipe(out_pipe, res_id);
            }
        }

        __kernel void test_pipe_max_packet_size_read(__read_only pipe TestStruct in_pipe, __global TestStruct *dst)
        {
            int gid = get_global_id(0);
            reserve_id_t res_id;

            res_id = reserve_read_pipe(in_pipe, 1);
            if(is_valid_reserve_id(res_id))
            {
                read_pipe(in_pipe, res_id, 0, &dst[gid]);
                commit_read_pipe(in_pipe, res_id);
            }
        }
        )";
    // clang-format on

    std::string kernel_source = source.str();
    const char *sources[] = { kernel_source.c_str() };

    // Create producer kernel
    err = create_single_kernel_helper_with_build_options(
        context, &program, &kernel[0], 1, sources, kernelName[0],
        "-cl-std=CL2.0");
    test_error_ret(err, " Error creating program", -1);

    //Create consumer kernel
    kernel[1] = clCreateKernel(program, kernelName[1], &err);
    test_error_ret(err, " Error creating kernel", -1);

    err = clSetKernelArg(kernel[0], 0, sizeof(cl_mem), (void*)&buffers[0]);
    err |= clSetKernelArg(kernel[0], 1, sizeof(cl_mem), (void*)&pipe);
    err |= clSetKernelArg(kernel[1], 0, sizeof(cl_mem), (void*)&pipe);
    err |= clSetKernelArg(kernel[1], 1, sizeof(cl_mem), (void*)&buffers[1]);
    test_error_ret(err, " clSetKernelArg failed", -1);

    // Launch Producer kernel
    err = clEnqueueNDRangeKernel( queue, kernel[0], 1, NULL, global_work_size, NULL, 0, NULL, &producer_sync_event );
    test_error_ret(err, " clEnqueueNDRangeKernel failed", -1);

    // Launch Consumer kernel
    err = clEnqueueNDRangeKernel( queue, kernel[1], 1, NULL, global_work_size, NULL, 1, &producer_sync_event, &consumer_sync_event );
    test_error_ret(err, " clEnqueueNDRangeKernel failed", -1);

    err = clEnqueueReadBuffer(queue, buffers[1], true, 0, size, outptr, 1, &consumer_sync_event, NULL);
    test_error_ret(err, " clEnqueueReadBuffer failed", -1);

    if( verify_result( inptr, outptr, size)){
        log_error("test_pipe_max_packet_size failed\n");
    }
    else {
        log_info("test_pipe_max_packet_size passed\n");
    }

    return 0;
}

int test_pipe_max_active_reservations(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
    clMemWrapper pipe;
    clMemWrapper buffers[2];
    clMemWrapper buf_reservations;
    clMemWrapper buf_status;
    clMemWrapper buf_reserve_id_t_size;
    clMemWrapper buf_reserve_id_t_size_aligned;
    cl_int *inptr;
    void *outptr;
    int size, i;
    clProgramWrapper program;
    clKernelWrapper kernel[3];
    size_t global_work_size[3];
    cl_int err;
    int status = 0;
    cl_uint max_active_reservations = 0;
    cl_ulong max_global_size = 0;
    int reserve_id_t_size;
    int temp;
    clEventWrapper sync_event = NULL;
    clEventWrapper read_event = NULL;
    BufferOwningPtr<cl_int> BufferInPtr;
    BufferOwningPtr<cl_int> BufferOutPtr;
    MTdataHolder d(gRandomSeed);
    const char *kernelName[3] = { "test_pipe_max_active_reservations_write",
                                  "test_pipe_max_active_reservations_read",
                                  "pipe_get_reserve_id_t_size" };

    size_t min_alignment = get_min_alignment(context);

    std::stringstream source;

    global_work_size[0] = 1;

    err = clGetDeviceInfo(deviceID, CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS,
                          sizeof(max_active_reservations),
                          (void *)&max_active_reservations, NULL);
    test_error_ret(err, " clGetDeviceInfo failed", -1);

    err = clGetDeviceInfo(deviceID, CL_DEVICE_GLOBAL_MEM_SIZE,
                          sizeof(max_global_size), (void *)&max_global_size,
                          NULL);
    test_error_ret(err, " clGetDeviceInfo failed", -1);

    max_active_reservations = (max_active_reservations > max_global_size)
        ? 1 << 16
        : max_active_reservations;

    if (max_active_reservations < 1)
    {
        log_error("The device should support minimum active reservations of 1");
        return -1;
    }

    // To get reserve_id_t size
    buf_reserve_id_t_size = clCreateBuffer(context, CL_MEM_HOST_READ_ONLY, sizeof(reserve_id_t_size), NULL, &err);
    test_error_ret(err, " clCreateBuffer failed", -1);

    // clang-format off
    source << R"(
        __kernel void test_pipe_max_active_reservations_write(__global int *src, __write_only pipe int out_pipe, __global char *reserve_id, __global int *reserve_id_t_size_aligned, __global int *status)
        {
            __global reserve_id_t *res_id_ptr;
            int reserve_idx;
            int commit_idx;

            for(reserve_idx = 0; reserve_idx < )" << max_active_reservations << R"(; reserve_idx++)
            {
                res_id_ptr = (__global reserve_id_t*)(reserve_id + reserve_idx*reserve_id_t_size_aligned[0]);
                *res_id_ptr = reserve_write_pipe(out_pipe, 1);
                if(is_valid_reserve_id(res_id_ptr[0]))
                {
                    write_pipe(out_pipe, res_id_ptr[0], 0, &src[reserve_idx]);
                }
                else
                {
                    *status = -1;
                    return;
                }
            }

            for(commit_idx = 0; commit_idx < )" << max_active_reservations << R"(; commit_idx++)
            {
                res_id_ptr = (__global reserve_id_t*)(reserve_id + commit_idx*reserve_id_t_size_aligned[0]);
                commit_write_pipe(out_pipe, res_id_ptr[0]);
            }
        }

        __kernel void test_pipe_max_active_reservations_read(__read_only pipe int in_pipe, __global int *dst, __global char *reserve_id, __global int *reserve_id_t_size_aligned, __global int *status)
        {
            __global reserve_id_t *res_id_ptr;
            int reserve_idx;
            int commit_idx;

            for(reserve_idx = 0; reserve_idx < )" << max_active_reservations << R"(; reserve_idx++)
            {
                res_id_ptr = (__global reserve_id_t*)(reserve_id + reserve_idx*reserve_id_t_size_aligned[0]);
                *res_id_ptr = reserve_read_pipe(in_pipe, 1);

                if(is_valid_reserve_id(res_id_ptr[0]))
                {
                    read_pipe(in_pipe, res_id_ptr[0], 0, &dst[reserve_idx]);
                }
                else
                {
                    *status = -1;
                    return;
                }
            }

            for(commit_idx = 0; commit_idx < )" << max_active_reservations << R"(; commit_idx++)
            {
                res_id_ptr = (__global reserve_id_t*)(reserve_id + commit_idx*reserve_id_t_size_aligned[0]);
                commit_read_pipe(in_pipe, res_id_ptr[0]);
            }
        }

        __kernel void pipe_get_reserve_id_t_size(__global int *reserve_id_t_size)
        {
            *reserve_id_t_size = sizeof(reserve_id_t);
        }
        )";
    // clang-format on

    std::string kernel_source = source.str();
    const char *sources[] = { kernel_source.c_str() };

    // Create producer kernel
    err = create_single_kernel_helper_with_build_options(
        context, &program, &kernel[0], 1, sources, kernelName[0],
        "-cl-std=CL2.0");
    test_error_ret(err, " Error creating program", -1);

    // Create consumer kernel
    kernel[1] = clCreateKernel(program, kernelName[1], &err);
    test_error_ret(err, " Error creating kernel", -1);

    // Create size query kernel for reserve_id_t
    kernel[2] = clCreateKernel(program, kernelName[2], &err);
    test_error_ret(err, " Error creating kernel", -1);

    err = clSetKernelArg(kernel[2], 0, sizeof(cl_mem), (void*)&buf_reserve_id_t_size);
    test_error_ret(err, " clSetKernelArg failed", -1);

    //Launch size query kernel for reserve_id_t
    err = clEnqueueNDRangeKernel( queue, kernel[2], 1, NULL, global_work_size, NULL, 0, NULL, &sync_event );
    test_error_ret(err, " clEnqueueNDRangeKernel failed", -1);

    err = clEnqueueReadBuffer(queue, buf_reserve_id_t_size, true, 0, sizeof(reserve_id_t_size), &reserve_id_t_size, 1, &sync_event, &read_event);
    test_error_ret(err, " clEnqueueReadBuffer failed", -1);

    err = clWaitForEvents(1, &read_event);
    test_error_ret(err, " clWaitForEvents failed", -1);

    // Round reserve_id_t_size to the nearest power of 2
    temp = 1;
    while(temp < reserve_id_t_size)
        temp *= 2;
    reserve_id_t_size = temp;

    size = sizeof(cl_int) * max_active_reservations;
    inptr = (cl_int *)align_malloc(size, min_alignment);

    for(i = 0; i < max_active_reservations; i++){
        inptr[i] = (int)genrand_int32(d);
    }
    BufferInPtr.reset(inptr, nullptr, 0, size, true);

    buffers[0] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, size, inptr, &err);
    test_error_ret(err, " clCreateBuffer failed", -1);

    outptr = align_malloc(size, min_alignment);
    BufferOutPtr.reset(outptr, nullptr, 0, size, true);

    buffers[1] = clCreateBuffer(context, CL_MEM_HOST_READ_ONLY, size, NULL, &err);
    test_error_ret(err, " clCreateBuffer failed", -1);

    buf_reserve_id_t_size_aligned = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, sizeof(reserve_id_t_size), &reserve_id_t_size, &err);
    test_error_ret(err, " clCreateBuffer failed", -1);

    //For error status
    buf_status = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR,  sizeof(int), &status, &err);
    test_error_ret(err, " clCreateBuffer failed", -1);

    pipe = clCreatePipe(context, CL_MEM_HOST_NO_ACCESS, sizeof(int), max_active_reservations, NULL, &err);
    test_error_ret(err, " clCreatePipe failed", -1);

    // Global buffer to hold all active reservation ids
    buf_reservations = clCreateBuffer(context, CL_MEM_HOST_NO_ACCESS, reserve_id_t_size*max_active_reservations, NULL, &err);
    test_error_ret(err, " clCreateBuffer failed", -1);

    err = clSetKernelArg(kernel[0], 0, sizeof(cl_mem), (void*)&buffers[0]);
    err |= clSetKernelArg(kernel[0], 1, sizeof(cl_mem), (void*)&pipe);
    err |= clSetKernelArg(kernel[0], 2, sizeof(cl_mem), (void*)&buf_reservations);
    err |= clSetKernelArg(kernel[0], 3, sizeof(cl_mem), (void*)&buf_reserve_id_t_size_aligned);
    err |= clSetKernelArg(kernel[0], 4, sizeof(cl_mem), (void*)&buf_status);
    test_error_ret(err, " clSetKernelArg failed", -1);

    err = clSetKernelArg(kernel[1], 0, sizeof(cl_mem), (void*)&pipe);
    err |= clSetKernelArg(kernel[1], 1, sizeof(cl_mem), (void*)&buffers[1]);
    err |= clSetKernelArg(kernel[1], 2, sizeof(cl_mem), (void*)&buf_reservations);
    err |= clSetKernelArg(kernel[1], 3, sizeof(cl_mem), (void*)&buf_reserve_id_t_size_aligned);
    err |= clSetKernelArg(kernel[1], 4, sizeof(cl_mem), (void*)&buf_status);
    test_error_ret(err, " clSetKernelArg failed", -1);

    clReleaseEvent(sync_event);

    // Launch Producer kernel
    err = clEnqueueNDRangeKernel(queue, kernel[0], 1, NULL, global_work_size, NULL, 0, NULL, &sync_event);
    test_error_ret(err, " clEnqueueNDRangeKernel failed", -1);

    err = clEnqueueReadBuffer(queue, buf_status, true, 0, sizeof(int), &status, 1, &sync_event, NULL);
    test_error_ret(err, " clEnqueueReadBuffer failed", -1);

    if(status != 0)
    {
        log_error("test_pipe_max_active_reservations failed\n");
        return -1;
    }

    clReleaseEvent(sync_event);
    // Launch Consumer kernel
    err = clEnqueueNDRangeKernel(queue, kernel[1], 1, NULL, global_work_size, NULL, 0, NULL, &sync_event);
    test_error_ret(err, " clEnqueueNDRangeKernel failed", -1);

    err = clEnqueueReadBuffer(queue, buf_status, true, 0, sizeof(int), &status, 1, &sync_event, NULL);
    test_error_ret(err, " clEnqueueReadBuffer failed", -1);

    if(status != 0)
    {
        log_error("test_pipe_max_active_reservations failed\n");
        return -1;
    }

    err = clEnqueueReadBuffer(queue, buffers[1], true, 0, size, outptr, 1, &sync_event, NULL);
    test_error_ret(err, " clEnqueueReadBuffer failed", -1);

    if( verify_result_int( inptr, outptr, max_active_reservations)){
        log_error("test_pipe_max_active_reservations failed\n");
        return -1;
    }
    else {
        log_info("test_pipe_max_active_reservations passed\n");
    }

    return 0;
}