<commit_before>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <af/dim4.hpp>
#include <Array.hpp>
#include <iostream>
#include <stdexcept>
#include <copy.hpp>
#include <scalar.hpp>
#include <JIT/BufferNode.hpp>

using af::dim4;

namespace opencl
{
    using std::ostream;

    template<typename T>
    Array<T>::Array(af::dim4 dims) :
        ArrayInfo(dims, af::dim4(0,0,0,0), calcStrides(dims), (af_dtype)dtype_traits<T>::af_type),
        data(),
        parent(), node(), ready(true)
    {
        if (elements() > 0) data = cl::Buffer(getContext(),
                                              CL_MEM_READ_WRITE,
                                              ArrayInfo::elements()*sizeof(T));
    }

    template<typename T>
    Array<T>::Array(af::dim4 dims, JIT::Node_ptr n) :
        ArrayInfo(dims, af::dim4(0,0,0,0), calcStrides(dims), (af_dtype)dtype_traits<T>::af_type),
        data(),
        parent(), node(n), ready(false)
    {
    }

    template<typename T>
    Array<T>::Array(af::dim4 dims, const T * const in_data) :
        ArrayInfo(dims, af::dim4(0,0,0,0), calcStrides(dims), (af_dtype)dtype_traits<T>::af_type),
        data(getContext(), CL_MEM_READ_WRITE, ArrayInfo::elements()*sizeof(T)),
        parent(), node(), ready(true)
    {
        getQueue().enqueueWriteBuffer(data,CL_TRUE,0,sizeof(T)*ArrayInfo::elements(),in_data);
    }

    template<typename T>
    Array<T>::Array(af::dim4 dims, cl_mem mem) :
        ArrayInfo(dims, af::dim4(0,0,0,0), calcStrides(dims), (af_dtype)dtype_traits<T>::af_type),
        data(mem),
        parent(), node(), ready(true)
    {
    }

    template<typename T>
    Array<T>::Array(const Array<T>& parnt, const dim4 &dims, const dim4 &offset, const dim4 &stride) :
        ArrayInfo(dims, offset, stride, (af_dtype)dtype_traits<T>::af_type),
        data(0),
        parent(&parnt), node(), ready(true)
    { }


    template<typename T>
    Array<T>::Array(Param &tmp) :
        ArrayInfo(af::dim4(tmp.info.dims[0], tmp.info.dims[1], tmp.info.dims[2], tmp.info.dims[3]),
                  af::dim4(0, 0, 0, 0),
                  af::dim4(tmp.info.strides[0], tmp.info.strides[1],
                           tmp.info.strides[2], tmp.info.strides[3]),
                  (af_dtype)dtype_traits<T>::af_type),
        data(tmp.data),
        parent(), node(), ready(true)
    {
    }

    template<typename T>
    Array<T>::~Array()
    { }

    using JIT::BufferNode;
    using JIT::Node;
    using JIT::Node_ptr;

    template<typename T>
    Node_ptr Array<T>::getNode() const
    {
        if (!node) {
            BufferNode *buf_node = new BufferNode(dtype_traits<T>::getName(),
                                                  shortname<T>(true), *this);
            const_cast<Array<T> *>(this)->node = Node_ptr(reinterpret_cast<Node *>(buf_node));
        }

        return node;
    }

    using af::dim4;

    template<typename T>
    Array<T> *
    createNodeArray(const dim4 &dims, Node_ptr node)
    {
        return new Array<T>(dims, node);
    }

    template<typename T>
    Array<T> *
    createSubArray(const Array<T>& parent, const dim4 &dims, const dim4 &offset, const dim4 &stride)
    {

        Array<T> *out = new Array<T>(parent, dims, offset, stride);

        if (stride[0] != 1 ||
            stride[1] <  0 ||
            stride[2] <  0 ||
            stride[3] <  0) {

            out = copyArray(*out);
        }

        return out;
    }

    template<typename T>
    Array<T> *
    createRefArray(const Array<T>& parent, const dim4 &dims, const dim4 &offset, const dim4 &stride)
    {
        return new Array<T>(parent, dims, offset, stride);
    }

    template<typename T>
    Array<T> *
    createHostDataArray(const dim4 &size, const T * const data)
    {
        Array<T> *out = new Array<T>(size, data);
        return out;
    }

    template<typename T>
    Array<T> *
    createDeviceDataArray(const dim4 &size, const void *data)
    {
        Array<T> *out = new Array<T>(size, (cl_mem)(data));
        return out;
    }

    template<typename T>
    Array<T>*
    createValueArray(const dim4 &size, const T& value)
    {
        return createScalarNode<T>(size, value);
    }

    template<typename T>
    Array<T>*
    createEmptyArray(const dim4 &size)
    {
        Array<T> *out = new Array<T>(size);
        return out;
    }

    template<typename inType, typename outType>
    Array<outType> *
    createPaddedArray(Array<inType> const &in, dim4 const &dims, outType default_value, double factor)
    {
        Array<outType> *ret = createEmptyArray<outType>(dims);

        copy<inType, outType>(*ret, in, default_value, factor);

        return ret;
    }

    template<typename T>
    Array<T>*
    createParamArray(Param &tmp)
    {
        Array<T> *out = new Array<T>(tmp);
        return out;<commit_msg>Added double precision checks in opencl<commit_after>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <af/dim4.hpp>
#include <Array.hpp>
#include <iostream>
#include <stdexcept>
#include <copy.hpp>
#include <scalar.hpp>
#include <JIT/BufferNode.hpp>
#include <err_opencl.hpp>

using af::dim4;

namespace opencl
{
    using std::ostream;

    template<typename T>
    Array<T>::Array(af::dim4 dims) :
        ArrayInfo(dims, af::dim4(0,0,0,0), calcStrides(dims), (af_dtype)dtype_traits<T>::af_type),
        data(),
        parent(), node(), ready(true)
    {
        if (elements() > 0) data = cl::Buffer(getContext(),
                                              CL_MEM_READ_WRITE,
                                              ArrayInfo::elements()*sizeof(T));
    }

    template<typename T>
    Array<T>::Array(af::dim4 dims, JIT::Node_ptr n) :
        ArrayInfo(dims, af::dim4(0,0,0,0), calcStrides(dims), (af_dtype)dtype_traits<T>::af_type),
        data(),
        parent(), node(n), ready(false)
    {
    }

    template<typename T>
    Array<T>::Array(af::dim4 dims, const T * const in_data) :
        ArrayInfo(dims, af::dim4(0,0,0,0), calcStrides(dims), (af_dtype)dtype_traits<T>::af_type),
        data(getContext(), CL_MEM_READ_WRITE, ArrayInfo::elements()*sizeof(T)),
        parent(), node(), ready(true)
    {
        getQueue().enqueueWriteBuffer(data,CL_TRUE,0,sizeof(T)*ArrayInfo::elements(),in_data);
    }

    template<typename T>
    Array<T>::Array(af::dim4 dims, cl_mem mem) :
        ArrayInfo(dims, af::dim4(0,0,0,0), calcStrides(dims), (af_dtype)dtype_traits<T>::af_type),
        data(mem),
        parent(), node(), ready(true)
    {
    }

    template<typename T>
    Array<T>::Array(const Array<T>& parnt, const dim4 &dims, const dim4 &offset, const dim4 &stride) :
        ArrayInfo(dims, offset, stride, (af_dtype)dtype_traits<T>::af_type),
        data(0),
        parent(&parnt), node(), ready(true)
    { }


    template<typename T>
    Array<T>::Array(Param &tmp) :
        ArrayInfo(af::dim4(tmp.info.dims[0], tmp.info.dims[1], tmp.info.dims[2], tmp.info.dims[3]),
                  af::dim4(0, 0, 0, 0),
                  af::dim4(tmp.info.strides[0], tmp.info.strides[1],
                           tmp.info.strides[2], tmp.info.strides[3]),
                  (af_dtype)dtype_traits<T>::af_type),
        data(tmp.data),
        parent(), node(), ready(true)
    {
    }

    template<typename T>
    Array<T>::~Array()
    { }

    using JIT::BufferNode;
    using JIT::Node;
    using JIT::Node_ptr;

    template<typename T>
    Node_ptr Array<T>::getNode() const
    {
        if (!node) {
            BufferNode *buf_node = new BufferNode(dtype_traits<T>::getName(),
                                                  shortname<T>(true), *this);
            const_cast<Array<T> *>(this)->node = Node_ptr(reinterpret_cast<Node *>(buf_node));
        }

        return node;
    }

    using af::dim4;

    template<typename T>
    Array<T> *
    createNodeArray(const dim4 &dims, Node_ptr node)
    {
        return new Array<T>(dims, node);
    }

    template<typename T>
    Array<T> *
    createSubArray(const Array<T>& parent, const dim4 &dims, const dim4 &offset, const dim4 &stride)
    {

        Array<T> *out = new Array<T>(parent, dims, offset, stride);

        if (stride[0] != 1 ||
            stride[1] <  0 ||
            stride[2] <  0 ||
            stride[3] <  0) {

            out = copyArray(*out);
        }

        return out;
    }

    template<typename T>
    Array<T> *
    createRefArray(const Array<T>& parent, const dim4 &dims, const dim4 &offset, const dim4 &stride)
    {
        return new Array<T>(parent, dims, offset, stride);
    }

    template<typename T>
    Array<T> *
    createHostDataArray(const dim4 &size, const T * const data)
    {
        if ((std::is_same<T, double>::value || std::is_same<T, cdouble>::value) &&
            !opencl::isDoubleSupported(opencl::getActiveDeviceId())) {
            TYPE_ERROR(1, (std::is_same<T, double>::value ? f64 : c64));
        }
        Array<T> *out = new Array<T>(size, data);
        return out;
    }

    template<typename T>
    Array<T> *
    createDeviceDataArray(const dim4 &size, const void *data)
    {
        if ((std::is_same<T, double>::value || std::is_same<T, cdouble>::value) &&
            !opencl::isDoubleSupported(opencl::getActiveDeviceId())) {
            TYPE_ERROR(1, (std::is_same<T, double>::value ? f64 : c64));
        }
        Array<T> *out = new Array<T>(size, (cl_mem)(data));
        return out;
    }

    template<typename T>
    Array<T>*
    createValueArray(const dim4 &size, const T& value)
    {
        if ((std::is_same<T, double>::value || std::is_same<T, cdouble>::value) &&
            !opencl::isDoubleSupported(opencl::getActiveDeviceId())) {
            TYPE_ERROR(1, (std::is_same<T, double>::value ? f64 : c64));
        }
        return createScalarNode<T>(size, value);
    }

    template<typename T>
    Array<T>*
    createEmptyArray(const dim4 &size)
    {
        if ((std::is_same<T, double>::value || std::is_same<T, cdouble>::value) &&
            !opencl::isDoubleSupported(opencl::getActiveDeviceId())) {
            TYPE_ERROR(1, (std::is_same<T, double>::value ? f64 : c64));
        }
        Array<T> *out = new Array<T>(size);
        return out;
    }

    template<typename inType, typename outType>
    Array<outType> *
    createPaddedArray(Array<inType> const &in, dim4 const &dims, outType default_value, double factor)
    {
        Array<outType> *ret = createEmptyArray<outType>(dims);

        copy<inType, outType>(*ret, in, default_value, factor);

        return ret;
    }

    template<typename T>
    Array<T>*
    createParamArray(Param &tmp)
    {
        if ((std::is_same<T, double>::value || std::is_same<T, cdouble>::value) &&
            !opencl::isDoubleSupported(opencl::getActiveDeviceId())) {
            TYPE_ERROR(1, (std::is_same<T, double>::value ? f64 : c64));
        }
        Array<T> *out = new Array<T>(tmp);
        return out;
{'fraction_non_alphanumeric': 0.1712048716833406, 'fraction_numerical': 0.015050021748586342, 'mean_word_length': 2.6264984227129338, 'pattern_counts': {'":': 0, '<': 169, '<?xml version=': 0, '>': 167, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5873178', 'n_tokens_mistral': 3837, 'n_tokens_neox': 3795, 'n_words': 751}