//
// 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "procs.h"



cl_int get_type_size( cl_context context, cl_command_queue queue, const char *type, cl_ulong *size, cl_device_id device  )
{
    const char *sizeof_kernel_code[4] =
    {
        "", /* optional pragma string */
        "__kernel __attribute__((reqd_work_group_size(1,1,1))) void test_sizeof(__global uint *dst) \n"
        "{\n"
        "   dst[0] = (uint) sizeof( ", type, " );\n"
        "}\n"
    };

    cl_program  p;
    cl_kernel   k;
    cl_mem      m;
    cl_uint        temp;


    if (!strncmp(type, "double", 6))
    {
        sizeof_kernel_code[0] = "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n";
    }
    else if (!strncmp(type, "half", 4))
    {
        sizeof_kernel_code[0] = "#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n";
    }
    cl_int err = create_single_kernel_helper_with_build_options(
        context, &p, &k, 4, sizeof_kernel_code, "test_sizeof", nullptr);
    if( err )
        return err;

    m = clCreateBuffer( context, CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, sizeof( cl_ulong ), size, &err );
    if( NULL == m )
    {
        clReleaseProgram( p );
        clReleaseKernel( k );
        log_error("\nclCreateBuffer FAILED\n");
        return err;
    }

    err = clSetKernelArg( k, 0, sizeof( cl_mem ), &m );
    if( err )
    {
        clReleaseProgram( p );
        clReleaseKernel( k );
        clReleaseMemObject( m );
        log_error("\nclSetKernelArg FAILED\n");
        return err;
    }

    err = clEnqueueTask( queue, k, 0, NULL, NULL );
    clReleaseProgram( p );
    clReleaseKernel( k );
    if( err )
    {
        clReleaseMemObject( m );
        log_error( "\nclEnqueueTask FAILED\n" );
        return err;
    }

    err = clEnqueueReadBuffer( queue, m, CL_TRUE, 0, sizeof( cl_uint ), &temp, 0, NULL, NULL );
    clReleaseMemObject( m );
    if( err )
        log_error( "\nclEnqueueReadBuffer FAILED\n" );

    *size = (cl_ulong) temp;

    return err;
}

typedef struct size_table
{
    const char *name;
    cl_ulong   size;
    cl_ulong   cl_size;
}size_table;

const size_table  scalar_table[] =
{
    // Fixed size entries from table 6.1
    {  "char",              1,  sizeof( cl_char )   },
    {  "uchar",             1,  sizeof( cl_uchar)   },
    {  "unsigned char",     1,  sizeof( cl_uchar)   },
    {  "short",             2,  sizeof( cl_short)   },
    {  "ushort",            2,  sizeof( cl_ushort)  },
    {  "unsigned short",    2,  sizeof( cl_ushort)  },
    {  "int",               4,  sizeof( cl_int )    },
    {  "uint",              4,  sizeof( cl_uint)    },
    {  "unsigned int",      4,  sizeof( cl_uint)    },
    {  "float",             4,  sizeof( cl_float)   },
    {  "long",              8,  sizeof( cl_long )   },
    {  "ulong",             8,  sizeof( cl_ulong)   },
    {  "unsigned long",     8,  sizeof( cl_ulong)   }
};

const size_table  vector_table[] =
{
    // Fixed size entries from table 6.1
    {  "char",      1,  sizeof( cl_char )   },
    {  "uchar",     1,  sizeof( cl_uchar)   },
    {  "short",     2,  sizeof( cl_short)   },
    {  "ushort",    2,  sizeof( cl_ushort)  },
    {  "int",       4,  sizeof( cl_int )    },
    {  "uint",      4,  sizeof( cl_uint)    },
    {  "float",     4,  sizeof( cl_float)   },
    {  "long",      8,  sizeof( cl_long )   },
    {  "ulong",     8,  sizeof( cl_ulong)   }
};

const char  *ptr_table[] =
{
    "global void*",
    "size_t",
    "sizeof(int)",      // check return type of sizeof
    "ptrdiff_t"
};

const char *other_types[] =
{
    "event_t",
    "image2d_t",
    "image3d_t",
    "sampler_t"
};

static int IsPowerOfTwo( cl_ulong x ){ return 0 == (x & (x-1)); }

int test_sizeof(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
{
    size_t i, j;
    cl_ulong test;
    cl_uint ptr_size = CL_UINT_MAX;
    cl_int err = CL_SUCCESS;

    // Check address space size
    err = clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS, sizeof(ptr_size), &ptr_size, NULL);
    if( err || ptr_size > 64)
    {
        log_error( "FAILED:  Unable to get CL_DEVICE_ADDRESS_BITS for device %p\n", device );
        return -1;
    }
    log_info( "\tCL_DEVICE_ADDRESS_BITS = %u\n", ptr_size );
    ptr_size /= 8;

    // Test standard scalar sizes
    for( i = 0; i < sizeof( scalar_table ) / sizeof( scalar_table[0] ); i++ )
    {
        if( ! gHasLong &&
           (0 == strcmp(scalar_table[i].name, "long") ||
            0 == strcmp(scalar_table[i].name, "ulong") ||
            0 == strcmp(scalar_table[i].name, "unsigned long")))
        {
            log_info("\nLongs are not supported by this device. Skipping test.\t");
            continue;
        }

        test = CL_ULONG_MAX;
        err = get_type_size( context, queue, scalar_table[i].name, &test, device);
        if( err )
            return err;
        if( test != scalar_table[i].size )
        {
            log_error( "\nFAILED: Type %s has size %lld, but expected size %lld!\n", scalar_table[i].name, test, scalar_table[i].size );
            return -1;
        }
        if( test != scalar_table[i].cl_size )
        {
            log_error( "\nFAILED: Type %s has size %lld, but cl_ size is %lld!\n", scalar_table[i].name, test, scalar_table[i].cl_size );
            return -2;
        }
        log_info( "%16s", scalar_table[i].name );
    }
    log_info( "\n" );

    // Test standard vector sizes
    for( j = 2; j <= 16; j *= 2 )
    {
        // For each vector size, iterate through types
        for( i = 0; i < sizeof( vector_table ) / sizeof( vector_table[0] ); i++ )
        {
            if( !gHasLong &&
               (0 == strcmp(vector_table[i].name, "long") ||
                0 == strcmp(vector_table[i].name, "ulong")))
            {
                log_info("\nLongs are not supported by this device. Skipping test.\t");
                continue;
            }

            char name[32];
            sprintf( name, "%s%ld", vector_table[i].name, j );

            test = CL_ULONG_MAX;
            err = get_type_size( context, queue, name, &test, device  );
            if( err )
                return err;
            if( test != j * vector_table[i].size )
            {
                log_error( "\nFAILED: Type %s has size %lld, but expected size %lld!\n", name, test, j * vector_table[i].size );
                return -1;
            }
            if( test != j * vector_table[i].cl_size )
            {
                log_error( "\nFAILED: Type %s has size %lld, but cl_ size is %lld!\n", name, test, j * vector_table[i].cl_size );
                return -2;
            }
            log_info( "%16s", name );
        }
        log_info( "\n" );
    }

    //Check that pointer sizes are correct
    for( i = 0; i < sizeof( ptr_table ) / sizeof( ptr_table[0] ); i++ )
    {
        test = CL_ULONG_MAX;
        err = get_type_size( context, queue, ptr_table[i], &test, device );
        if( err )
            return err;
        if( test != ptr_size )
        {
            log_error( "\nFAILED: Type %s has size %lld, but expected size %u!\n", ptr_table[i], test, ptr_size );
            return -1;
        }
        log_info( "%16s", ptr_table[i] );
    }

    // Check that intptr_t is large enough
    test = CL_ULONG_MAX;
    err = get_type_size( context, queue, "intptr_t", &test, device );
    if( err )
        return err;
    if( test < ptr_size )
    {
        log_error( "\nFAILED: intptr_t has size %lld, but must be at least %u!\n", test, ptr_size );
        return -1;
    }
    if( ! IsPowerOfTwo( test ) )
    {
        log_error( "\nFAILED: sizeof(intptr_t) is %lld, but must be a power of two!\n", test );
        return -2;
    }
    log_info( "%16s", "intptr_t" );

    // Check that uintptr_t is large enough
    test = CL_ULONG_MAX;
    err = get_type_size( context, queue, "uintptr_t", &test, device );
    if( err )
        return err;
    if( test < ptr_size )
    {
        log_error( "\nFAILED: uintptr_t has size %lld, but must be at least %u!\n", test, ptr_size );
        return -1;
    }
    if( ! IsPowerOfTwo( test ) )
    {
        log_error( "\nFAILED: sizeof(uintptr_t) is %lld, but must be a power of two!\n", test );
        return -2;
    }
    log_info( "%16s\n", "uintptr_t" );

    //Check that other types are powers of two
    for( i = 0; i < sizeof( other_types ) / sizeof( other_types[0] ); i++ )
    {
        if( 0 == strcmp(other_types[i], "image2d_t") &&
           checkForImageSupport( device ) == CL_IMAGE_FORMAT_NOT_SUPPORTED)
        {
            log_info("\nimages are not supported by this device. Skipping test.\t");
            continue;
        }

        if( gIsEmbedded &&
           0 == strcmp(other_types[i], "image3d_t") &&
           checkFor3DImageSupport( device ) == CL_IMAGE_FORMAT_NOT_SUPPORTED)
        {
            log_info("\n3D images are not supported by this device. Skipping test.\t");
            continue;
        }

        if( 0 == strcmp(other_types[i], "sampler_t") &&
           checkForImageSupport( device ) == CL_IMAGE_FORMAT_NOT_SUPPORTED)
        {
          log_info("\nimages are not supported by this device. Skipping test.\t");
          continue;
        }

        test = CL_ULONG_MAX;
        err = get_type_size( context, queue, other_types[i], &test, device );
        if( err )
            return err;
        if( ! IsPowerOfTwo( test ) )
        {
            log_error( "\nFAILED: Type %s has size %lld, which is not a power of two (section 6.1.5)!\n", other_types[i], test );
            return -1;
        }
        log_info( "%16s", other_types[i] );
    }
    log_info( "\n" );


    //Check double
    if( is_extension_available( device, "cl_khr_fp64" ) )
    {
        log_info( "\tcl_khr_fp64:" );
        test = CL_ULONG_MAX;
        err = get_type_size( context, queue, "double", &test, device );
        if( err )
            return err;
        if( test != 8 )
        {
            log_error( "\nFAILED: double has size %lld, but must be 8!\n", test );
            return -1;
        }
        log_info( "%16s", "double" );

        // Test standard vector sizes
        for( j = 2; j <= 16; j *= 2 )
        {
            char name[32];
            sprintf( name, "double%ld", j );

            test = CL_ULONG_MAX;
            err = get_type_size( context, queue, name, &test, device );
            if( err )
                return err;
            if( test != 8*j )
            {
                log_error( "\nFAILED: %s has size %lld, but must be %ld!\n", name, test, 8 * j);
                return -1;
            }
            log_info( "%16s", name );
        }
        log_info( "\n" );
    }

    //Check half
    if( is_extension_available( device, "cl_khr_fp16" ) )
    {
        log_info( "\tcl_khr_fp16:" );
        test = CL_ULONG_MAX;
        err = get_type_size( context, queue, "half", &test, device );
        if( err )
            return err;
        if( test != 2 )
        {
            log_error( "\nFAILED: half has size %lld, but must be 2!\n", test );
            return -1;
        }
        log_info( "%16s", "half" );

        // Test standard vector sizes
        for( j = 2; j <= 16; j *= 2 )
        {
            char name[32];
            sprintf( name, "half%ld", j );

            test = CL_ULONG_MAX;
            err = get_type_size( context, queue, name, &test, device );
            if( err )
                return err;
            if( test != 2*j )
            {
                log_error( "\nFAILED: %s has size %lld, but must be %ld!\n", name, test, 2 * j);
                return -1;
            }
            log_info( "%16s", name );
        }
        log_info( "\n" );
    }

    return err;
}


