/*
 * oclh_d_srr.clh
 *      Author: havock
 */
#ifndef OCLH_D_SRR_CLH_DECLS_
#define OCLH_D_SRR_CLH_DECLS_ 1
#include <oclh_hd_std_types.clh>

#if defined(_OCLH_OCL_HOST_HEADERS_) || defined(_OCLH_OCL_COMPILER_)
/*
 * current section is available for host just for memory size calculations
 */
#pragma pack(push,1)
typedef struct _GDT_VECTOR_SET_DESCRIPTION {
    __global flt32_t* pf32V;
             uint64_t u64VDim;
             uint64_t u64NofVs;
} _GDT_VS_DESC;
typedef struct _GDT_CONST_VECTOR_SET_DESCRIPTION {
    __global const flt32_t* pf32V;
                   uint64_t u64VDim;
                   uint64_t u64NofVs;
} _GDT_CVS_DESC;
#pragma pack(pop)
#endif /* defined(_OCLH_OCL_HOST_HEADERS_) || defined(_OCLH_OCL_COMPILER_) */

#ifdef _OCLH_OCL_COMPILER_
_GDT_VS_DESC _gdf_declVecSetFromTermOffset(__global flt32_t* const pf32V,
                                           __private const uint64_t u64VDim,
                                           __private const uint64_t u64VOffset,
                                           __private const uint64_t u64NofVecs);
_GDT_CVS_DESC _gdf_declConstVecSetFromTermOffset(
                                     __global  const flt32_t* const pf32V,
                                     __private const uint64_t       u64VDim,
                                     __private const uint64_t       u64VOffset,
                                     __private const uint64_t       u64NofVecs);
int32_t _gdf_dropOutVecs_f32_g(__private const _GDT_VS_DESC VS);
flt32_t _gdf_euclDst_f32_pp(__private const flt32_t* const pA,
                            __private const flt32_t* const pB,
                            __private const uint64_t       Dim);
flt32_t _gdf_euclDst_f32_gg(__global  const flt32_t* const pA,
                            __global  const flt32_t* const pB,
                            __private const	uint64_t       Dim);
int32_t _gdf_copyVec_f32_pp(__private       flt32_t* const pDst,
                            __private const flt32_t* const pSrc,
                            __private const uint64_t       Dim);
int32_t _gdf_copyVec_f32_gg(__global        flt32_t* const pDst,
                            __global  const flt32_t* const pSrc,
                            __private const uint64_t       Dim);
int32_t _gdf_copyVec_f32_pg(__private       flt32_t* const pDst,
                            __global  const flt32_t* const pSrc,
                            __private const uint64_t       Dim);
uint32_t CRC32b(__global  const uint8_t* const pu8Data,
                __private const uint64_t u64Sz);
#endif /* _OCLH_OCL_COMPILER_ */

#endif /* OCLH_D_SRR_CLH_DECLS_ */




#ifdef _OCLH_OCL_COMPILER_
#ifndef OCLH_D_SRR_CLH_IMPLS_
#define OCLH_D_SRR_CLH_IMPLS_ 1

_GDT_VS_DESC _gdf_declVecSetFromTermOffset(__global  flt32_t* const pf32V,
                                           __private const uint64_t u64VDim,
                                           __private const uint64_t u64VOffset,
                                           __private const uint64_t u64NofVecs){
    __private _GDT_VS_DESC desc={
        .pf32V=&pf32V[u64VOffset*u64VDim],
        .u64VDim=u64VDim,
        .u64NofVs=u64NofVecs
    };
    return(desc);
}
_GDT_CVS_DESC _gdf_declConstVecSetFromTermOffset(
                                           __global  const flt32_t* const pf32V,
                                           __private const uint64_t u64VDim,
                                           __private const uint64_t u64VOffset,
                                           __private const uint64_t u64NofVecs){
    __private _GDT_CVS_DESC desc={
        .pf32V=&pf32V[u64VOffset*u64VDim],
        .u64VDim=u64VDim,
        .u64NofVs=u64NofVecs
    };
    return(desc);
}
int32_t _gdf_dropOutVecs_f32_g(__private const _GDT_VS_DESC VS) {
    /*
     * use this function for one thread only
     * using the function in multithreaded case could lead to
     * an inseparable mix of the output result
     */
    __private uint64_t i=0ul;
    for(i=0ul; i<VS.u64NofVs; i++) {
        __private uint64_t j=0ul;
        __global const flt32_t* const pf32CurV=&VS.pf32V[i*VS.u64VDim];
        printf("# %lu # ",i);
        for(j=0; j<VS.u64VDim; j++) printf("%f ",pf32CurV[j]); printf("\n");
    }
    printf("\n");
    return(0);
}
flt32_t _gdf_euclDst_f32_pp(__private const flt32_t* const pA,
                            __private const flt32_t* const pB,
                            __private const uint64_t       Dim) {
    __private flt32_t S=0.0f, D=0.0f;
    __private uint64_t i=0ul;
    for(i=0ul; i<Dim; i++) { D=pA[i]-pB[i]; S+=(D*D); };
    return(sqrt(S));
}
flt32_t _gdf_euclDst_f32_gg(__global  const flt32_t* const pfA,
                            __global  const flt32_t* const pfB,
                            __private const uint64_t       Dim) {
    __private flt32_t S=0.0f, D=0.0f;
    __private uint64_t i=0ul;
    for(i=0; i<Dim; i++) { D=pfA[i]-pfB[i]; S+=(D*D); };
    return(sqrt(S));
}
int32_t _gdf_copyVec_f32_pp(__private       flt32_t* const pDst,
                            __private const flt32_t* const pSrc,
                            __private const uint64_t       Dim) {
    __private uint64_t i=0ul;
    for(i=0ul; i<Dim; i++) pDst[i]=pSrc[i];
    return(0);
}
int32_t _gdf_copyVec_f32_gg(__global        flt32_t* const pDst,
                            __global  const flt32_t* const pSrc,
                            __private const uint64_t       Dim) {
    __private uint64_t i=0ul;
    for(i=0ul; i<Dim; i++) pDst[i]=pSrc[i];
    return(0);
}
int32_t _gdf_copyVec_f32_pg(__private       flt32_t* const pDst,
                            __global  const flt32_t* const pSrc,
                            __private const uint64_t       Dim) {
    __private uint64_t i=0ul;
    for(i=0;i<Dim;i++) pDst[i]=pSrc[i];
    return(0);
}

uint32_t CRC32b(__global  const uint8_t* const pu8Data,
                __private const uint64_t       u64Sz) {
    __private uint64_t i=0ul;
    __private uint32_t byte=0u,
                       mask=0u;
                       crc=0xFFFFFFFF;
    for(i=0ul; i<u64Sz; i++) {
        __private int32_t j=0;
        byte=(uint32_t)(pu8Data[i]);
        crc=crc^byte;
        for(j=7; j>=0; j--) {
            mask=-(crc & 1);
            crc=(crc >> 1)^(0xEDB88320 & mask);
        }
    }
    return(crc);
}

#endif /* OCLH_D_SRR_CLH_IMPLS_ */
#endif /* _OCLH_OCL_COMPILER_ */
