<commit_before>// Copyright (c) 2014, Salesforce.com, Inc.  All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// - Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the
//   documentation and/or other materials provided with the distribution.
// - Neither the name of Salesforce.com nor the names of its contributors
//   may be used to endorse or promote products derived from this
//   software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#pragma once

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/gzip_stream.h>
#include <distributions/common.hpp>

namespace distributions
{
namespace protobuf
{

inline bool endswith (const char * filename, const char * suffix)
{
    return strlen(filename) >= strlen(suffix) and
        strcmp(filename + strlen(filename) - strlen(suffix), suffix) == 0;
}

class InFile
{
public:

    InFile (const char * filename) : filename_(filename)
    {
        if (strcmp(filename, "-") == 0 or strcmp(filename, "-.gz") == 0) {
            fid_ = STDIN_FILENO;
        } else {
            fid_ = open(filename, O_RDONLY | O_NOATIME);
            DIST_ASSERT(fid_ != -1, "failed to open input file " << filename);
        }

        file_ = new google::protobuf::io::FileInputStream(fid_);

        if (endswith(filename, ".gz")) {
            gzip_ = new google::protobuf::io::GzipInputStream(file_);
            stream_ = gzip_;
        } else {
            gzip_ = nullptr;
            stream_ = file_;
        }
    }

    ~InFile ()
    {
        delete gzip_;
        delete file_;
        if (fid_ != STDIN_FILENO) {
            close(fid_);
        }
    }

    template<class Message>
    void read (Message & message)
    {
        bool success = message.ParseFromZeroCopyStream(stream_);
        DIST_ASSERT(success, "failed to parse message from " << filename_);
    }

    template<class Message>
    uint32_t try_read_stream (Message & message)
    {
        google::protobuf::io::CodedInputStream coded(stream_);
        uint32_t message_size = 0;
        if (DIST_LIKELY(coded.ReadLittleEndian32(& message_size))) {
            auto old_limit = coded.PushLimit(message_size);
            bool success = message.ParseFromCodedStream(& coded);
            DIST_ASSERT(success, "failed to parse message from " << filename_);
            coded.PopLimit(old_limit);
            return message_size;
        } else {
            return 0;
        }
    }

private:

    const std::string filename_;
    int fid_;
    google::protobuf::io::FileInputStream * file_;
    google::protobuf::io::GzipInputStream * gzip_;
    google::protobuf::io::ZeroCopyInputStream * stream_;
};

class OutFile
{
public:

    OutFile (const char * filename) : filename_(filename)
    {
        if (strcmp(filename, "-") == 0 or strcmp(filename, "-.gz") == 0) {
            fid_ = STDOUT_FILENO;
        } else {
            fid_ = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664);
            DIST_ASSERT(fid_ != -1, "failed to open output file " << filename);
        }

        file_ = new google::protobuf::io::FileOutputStream(fid_);

        if (endswith(filename, ".gz")) {
            gzip_ = new google::protobuf::io::GzipOutputStream(file_);
            stream_ = gzip_;
        } else {
            gzip_ = nullptr;
            stream_ = file_;
        }
    }

    ~OutFile ()
    {
        delete gzip_;
        delete file_;
        if (fid_ != STDOUT_FILENO) {
            close(fid_);
        }
    }

    template<class Message>
    void write (Message & message)
    {
        DIST_ASSERT1(message.IsInitialized(), "message not initialized");
        bool success = message.SerializeToZeroCopyStream(stream_);
        DIST_ASSERT(success, "failed to serialize message to " << filename_);
    }

    template<class Message>
    void write_stream (Message & message)
    {
        google::protobuf::io::CodedOutputStream coded(stream_);
        DIST_ASSERT1(message.IsInitialized(), "message not initialized");
        uint32_t message_size = message.ByteSize();
        DIST_ASSERT1(message_size > 0, "zero sized message is not supported");
        coded.WriteLittleEndian32(message_size);
        message.SerializeWithCachedSizes(& coded);
    }

private:

    const std::string filename_;
    int fid_;
    google::protobuf::io::FileOutputStream * file_;
    google::protobuf::io::GzipOutputStream * gzip_;
    google::protobuf::io::ZeroCopyOutputStream * stream_;
};

} // namespace protobuf
} // namespace distributions
<commit_msg>Add InFile::cyclic_read_stream<commit_after>// Copyright (c) 2014, Salesforce.com, Inc.  All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// - Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the
//   documentation and/or other materials provided with the distribution.
// - Neither the name of Salesforce.com nor the names of its contributors
//   may be used to endorse or promote products derived from this
//   software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#pragma once

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/gzip_stream.h>
#include <distributions/common.hpp>

namespace distributions
{
namespace protobuf
{

inline bool endswith (const char * filename, const char * suffix)
{
    return strlen(filename) >= strlen(suffix) and
        strcmp(filename + strlen(filename) - strlen(suffix), suffix) == 0;
}

class InFile
{
public:

    InFile (const char * filename) : filename_(filename)
    {
        _open();
    }

    ~InFile ()
    {
        _close();
    }

    template<class Message>
    void read (Message & message)
    {
        bool success = message.ParseFromZeroCopyStream(stream_);
        DIST_ASSERT(success, "failed to parse message from " << filename_);
    }

    template<class Message>
    bool try_read_stream (Message & message)
    {
        google::protobuf::io::CodedInputStream coded(stream_);
        uint32_t message_size = 0;
        if (DIST_LIKELY(coded.ReadLittleEndian32(& message_size))) {
            auto old_limit = coded.PushLimit(message_size);
            bool success = message.ParseFromCodedStream(& coded);
            DIST_ASSERT(success, "failed to parse message from " << filename_);
            coded.PopLimit(old_limit);
            return true;
        } else {
            return false;
        }
    }

    template<class Message>
    void cyclic_read_stream (Message & message)
    {
        if (DIST_UNLIKELY(not try_read_stream(message))) {
            _close();
            _open();
            bool success = try_read_stream(message);
            DIST_ASSERT(success, "stream is empty");
        }
    }

private:

    void _open ()
    {
        if (filename_ == "-" or filename_ == "-.gz") {
            fid_ = STDIN_FILENO;
        } else {
            fid_ = open(filename_.c_str(), O_RDONLY | O_NOATIME);
            DIST_ASSERT(fid_ != -1, "failed to open input file " << filename_);
        }

        file_ = new google::protobuf::io::FileInputStream(fid_);

        if (endswith(filename_.c_str(), ".gz")) {
            gzip_ = new google::protobuf::io::GzipInputStream(file_);
            stream_ = gzip_;
        } else {
            gzip_ = nullptr;
            stream_ = file_;
        }
    }

    void _close ()
    {
        delete gzip_;
        delete file_;
        if (fid_ != STDIN_FILENO) {
            close(fid_);
        }
    }

    const std::string filename_;
    int fid_;
    google::protobuf::io::FileInputStream * file_;
    google::protobuf::io::GzipInputStream * gzip_;
    google::protobuf::io::ZeroCopyInputStream * stream_;
};

class OutFile
{
public:

    OutFile (const char * filename) : filename_(filename)
    {
        if (filename_ == "-" or filename_ == "-.gz") {
            fid_ = STDOUT_FILENO;
        } else {
            fid_ = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664);
            DIST_ASSERT(fid_ != -1, "failed to open output file " << filename);
        }

        file_ = new google::protobuf::io::FileOutputStream(fid_);

        if (endswith(filename, ".gz")) {
            gzip_ = new google::protobuf::io::GzipOutputStream(file_);
            stream_ = gzip_;
        } else {
            gzip_ = nullptr;
            stream_ = file_;
        }
    }

    ~OutFile ()
    {
        delete gzip_;
        delete file_;
        if (fid_ != STDOUT_FILENO) {
            close(fid_);
        }
    }

    template<class Message>
    void write (Message & message)
    {
        DIST_ASSERT1(message.IsInitialized(), "message not initialized");
        bool success = message.SerializeToZeroCopyStream(stream_);
        DIST_ASSERT(success, "failed to serialize message to " << filename_);
    }

    template<class Message>
    void write_stream (Message & message)
    {
        google::protobuf::io::CodedOutputStream coded(stream_);
        DIST_ASSERT1(message.IsInitialized(), "message not initialized");
        uint32_t message_size = message.ByteSize();
        coded.WriteLittleEndian32(message_size);
        message.SerializeWithCachedSizes(& coded);
    }

private:

    const std::string filename_;
    int fid_;
    google::protobuf::io::FileOutputStream * file_;
    google::protobuf::io::GzipOutputStream * gzip_;
    google::protobuf::io::ZeroCopyOutputStream * stream_;
};

} // namespace protobuf
} // namespace distributions
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2020 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include "etl/expr/base_temporary_expr.hpp"

#include "etl/impl/cudnn/bias_batch_mean.hpp"
#include "etl/impl/egblas/bias_batch_sum.hpp"

namespace etl {

/*!
 * \brief A transposition expression.
 * \tparam A The transposed type
 */
template <typename A, bool Mean>
struct bias_batch_mean_2d_expr : base_temporary_expr_un<bias_batch_mean_2d_expr<A, Mean>, A> {
    using value_type = value_t<A>;                           ///< The type of value of the expression
    using this_type  = bias_batch_mean_2d_expr<A, Mean>;     ///< The type of this expression
    using base_type  = base_temporary_expr_un<this_type, A>; ///< The base type
    using sub_traits = decay_traits<A>;                      ///< The traits of the sub type

    static constexpr auto storage_order = sub_traits::storage_order; ///< The sub storage order

    /*!
     * \brief Indicates if the temporary expression can be directly evaluated
     * using only GPU.
     */
    static constexpr bool gpu_computable = !Mean && cudnn_enabled && is_floating<A>;

    /*!
     * \brief Construct a new expression
     * \param a The sub expression
     */
    explicit bias_batch_mean_2d_expr(A a) : base_type(a) {
        //Nothing else to init
    }

    /*!
     * \brief Validate the transposition dimensions
     * \param a The input matrix
     * \þaram c The output matrix
     */
    template <typename C>
    static void check([[maybe_unused]] const A& a, [[maybe_unused]] const C& c) {
        static_assert(etl::dimensions<C>() == 1, "The output of bias_batch_mean_2d is a vector");
        static_assert(etl::dimensions<A>() == 2, "The input of bias_batch_mean_2d is a 2d matrix");

        if constexpr (all_fast<A, C>) {
            static_assert(etl::dim<1, A>() == etl::dim<0, C>(), "Invalid dimensions for bias_batch_mean_2d");
        } else {
            cpp_assert(etl::dim<1>(a) == etl::dim<0>(c), "Invalid dimensions for bias_batch_mean_2d");
        }
    }

    // Assignment functions

    /*!
     * \brief Assign to a matrix of the same storage order
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_2d only supported for ETL expressions");

        auto& a = this->a();

        using T = value_t<A>;

        check(a, lhs);

        [[maybe_unused]] const auto N = etl::dim<0>(a);
        [[maybe_unused]] const auto K = etl::dim<1>(a);

        if constexpr (!Mean && impl::egblas::has_sbias_batch_sum && all_row_major<A> && all_floating<A, L>) {
            auto t1 = smart_forward_gpu(a);
            t1.ensure_gpu_up_to_date();

            lhs.ensure_gpu_allocated();

            impl::egblas::bias_batch_sum(N, K, t1.gpu_memory(), 1, lhs.gpu_memory(), 1);

            lhs.validate_gpu();
            lhs.invalidate_cpu();
        } else if constexpr (Mean && impl::egblas::has_sbias_batch_mean && all_row_major<A> && all_floating<A, L>) {
            auto t1 = smart_forward_gpu(a);
            t1.ensure_gpu_up_to_date();

            lhs.ensure_gpu_allocated();

            impl::egblas::bias_batch_mean(N, K, t1.gpu_memory(), 1, lhs.gpu_memory(), 1);

            lhs.validate_gpu();
            lhs.invalidate_cpu();
        } else if constexpr (!Mean && cudnn_enabled && all_floating<A, L>) {
            impl::cudnn::bias_batch_mean_2d(smart_forward_gpu(a), lhs);
        } else {

            standard_evaluator::pre_assign_rhs(a);

            for (size_t k = 0; k < K; ++k) {
                T mean(0);

                for (size_t b = 0; b < N; ++b) {
                    mean += a(b, k);
                }

                if constexpr (Mean) {
                    lhs(k) = mean / N;
                } else {
                    lhs(k) = mean;
                }
            }
        }
    }

    /*!
     * \brief Add to the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_add_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_2d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        for (size_t k = 0; k < K; ++k) {
            T mean(0);

            for (size_t b = 0; b < N; ++b) {
                mean += a(b, k);
            }

            if constexpr (Mean) {
                lhs(k) += mean / N;
            } else {
                lhs(k) += mean;
            }
        }
    }

    /*!
     * \brief Sub from the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_sub_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_2d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        for (size_t k = 0; k < K; ++k) {
            T mean(0);

            for (size_t b = 0; b < N; ++b) {
                mean += a(b, k);
            }

            if constexpr (Mean) {
                lhs(k) -= mean / N;
            } else {
                lhs(k) -= mean;
            }
        }
    }

    /*!
     * \brief Multiply the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_mul_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_2d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        for (size_t k = 0; k < K; ++k) {
            T mean(0);

            for (size_t b = 0; b < N; ++b) {
                mean += a(b, k);
            }

            if constexpr (Mean) {
                lhs(k) *= mean / N;
            } else {
                lhs(k) *= mean;
            }
        }
    }

    /*!
     * \brief Divide the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_div_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_2d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        for (size_t k = 0; k < K; ++k) {
            T mean(0);

            for (size_t b = 0; b < N; ++b) {
                mean += a(b, k);
            }

            if constexpr (Mean) {
                lhs(k) /= mean / N;
            } else {
                lhs(k) /= mean;
            }
        }
    }

    /*!
     * \brief Modulo the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_mod_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_2d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        for (size_t k = 0; k < K; ++k) {
            T mean(0);

            for (size_t b = 0; b < N; ++b) {
                mean += a(b, k);
            }

            if constexpr (Mean) {
                lhs(k) %= mean / N;
            } else {
                lhs(k) %= mean;
            }
        }
    }

    /*!
     * \brief Print a representation of the expression on the given stream
     * \param os The output stream
     * \param expr The expression to print
     * \return the output stream
     */
    friend std::ostream& operator<<(std::ostream& os, const bias_batch_mean_2d_expr& expr) {
        if (Mean) {
            return os << "bias_batch_mean_2d(" << expr._a << ")";
        } else {
            return os << "bias_batch_sum_2d(" << expr._a << ")";
        }
    }
};

/*!
 * \brief Traits for a transpose expression
 * \tparam A The transposed sub type
 */
template <typename A, bool Mean>
struct etl_traits<etl::bias_batch_mean_2d_expr<A, Mean>> {
    using expr_t     = etl::bias_batch_mean_2d_expr<A, Mean>; ///< The expression type
    using sub_expr_t = std::decay_t<A>;                       ///< The sub expression type
    using sub_traits = etl_traits<sub_expr_t>;                ///< The sub traits
    using value_type = value_t<A>;                            ///< The value type of the expression

    static constexpr bool is_etl         = true;                                 ///< Indicates if the type is an ETL expression
    static constexpr bool is_transformer = false;                                ///< Indicates if the type is a transformer
    static constexpr bool is_view        = false;                                ///< Indicates if the type is a view
    static constexpr bool is_magic_view  = false;                                ///< Indicates if the type is a magic view
    static constexpr bool is_fast        = sub_traits::is_fast;                  ///< Indicates if the expression is fast
    static constexpr bool is_linear      = false;                                ///< Indicates if the expression is linear
    static constexpr bool is_thread_safe = true;                                 ///< Indicates if the expression is thread safe
    static constexpr bool is_value       = false;                                ///< Indicates if the expression is of value type
    static constexpr bool is_direct      = true;                                 ///< Indicates if the expression has direct memory access
    static constexpr bool is_generator   = false;                                ///< Indicates if the expression is a generator
    static constexpr bool is_padded      = false;                                ///< Indicates if the expression is padded
    static constexpr bool is_aligned     = true;                                 ///< Indicates if the expression is padded
    static constexpr bool is_temporary   = true;                                 ///< Indicates if the expression needs a evaluator visitor
    static constexpr order storage_order = sub_traits::storage_order;            ///< The expression's storage order
    static constexpr bool gpu_computable = is_gpu_t<value_type> && cuda_enabled; ///< Indicates if the expression can be computed on GPU

    /*!
     * \brief Indicates if the expression is vectorizable using the
     * given vector mode
     * \tparam V The vector mode
     */
    template <vector_mode_t V>
    static constexpr bool vectorizable = true;

    /*!
     * \brief Returns the DDth dimension of the expression
     * \return the DDth dimension of the expression
     */
    template <size_t DD>
    static constexpr size_t dim() {
        static_assert(DD == 0, "Invalid dimensions access");
        return decay_traits<A>::template dim<1>();
    }

    /*!
     * \brief Returns the dth dimension of the expression
     * \param e The sub expression
     * \param d The dimension to get
     * \return the dth dimension of the expression
     */
    static size_t dim(const expr_t& e, [[maybe_unused]] size_t d) {
        cpp_assert(d == 0, "Invalid dimensions access");

        return etl::dim<1>(e._a);
    }

    /*!
     * \brief Returns the size of the expression
     * \param e The sub expression
     * \return the size of the expression
     */
    static size_t size(const expr_t& e) {
        return etl::dim<1>(e._a);
    }

    /*!
     * \brief Returns the size of the expression
     * \return the size of the expression
     */
    static constexpr size_t size() {
        return decay_traits<A>::template dim<1>();
    }

    /*!
     * \brief Returns the number of dimensions of the expression
     * \return the number of dimensions of the expression
     */
    static constexpr size_t dimensions() {
        return 1;
    }
};

/*!
 * \brief Returns the transpose of the given expression.
 * \param value The expression
 * \return The transpose of the given expression.
 */
template <typename E>
bias_batch_mean_2d_expr<detail::build_type<E>, true> bias_batch_mean_2d(const E& value) {
    static_assert(is_etl_expr<E>, "etl::bias_batch_mean_2d can only be used on ETL expressions");
    static_assert(is_2d<E>, "etl::bias_batch_mean_2d is only defined for 2d input");

    return bias_batch_mean_2d_expr<detail::build_type<E>, true>{value};
}

/*!
 * \brief Returns the transpose of the given expression.
 * \param value The expression
 * \return The transpose of the given expression.
 */
template <typename E>
bias_batch_mean_2d_expr<detail::build_type<E>, false> bias_batch_sum_2d(const E& value) {
    static_assert(is_etl_expr<E>, "etl::bias_batch_sum_2d can only be used on ETL expressions");
    static_assert(is_2d<E>, "etl::bias_batch_sum_2d is only defined for 2d input");

    return bias_batch_mean_2d_expr<detail::build_type<E>, false>{value};
}

} //end of namespace etl
<commit_msg>Fix gpu_computable<commit_after>//=======================================================================
// Copyright (c) 2014-2020 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include "etl/expr/base_temporary_expr.hpp"

#include "etl/impl/cudnn/bias_batch_mean.hpp"
#include "etl/impl/egblas/bias_batch_sum.hpp"

namespace etl {

/*!
 * \brief A transposition expression.
 * \tparam A The transposed type
 */
template <typename A, bool Mean>
struct bias_batch_mean_2d_expr : base_temporary_expr_un<bias_batch_mean_2d_expr<A, Mean>, A> {
    using value_type = value_t<A>;                           ///< The type of value of the expression
    using this_type  = bias_batch_mean_2d_expr<A, Mean>;     ///< The type of this expression
    using base_type  = base_temporary_expr_un<this_type, A>; ///< The base type
    using sub_traits = decay_traits<A>;                      ///< The traits of the sub type

    static constexpr auto storage_order = sub_traits::storage_order; ///< The sub storage order

    /*!
     * \brief Indicates if the temporary expression can be directly evaluated
     * using only GPU.
     */
    static constexpr bool gpu_computable = (!Mean && cudnn_enabled && is_floating<A>)
            || (impl::egblas::has_sbias_batch_sum && all_row_major<A> && all_single_precision<A>)
            || (impl::egblas::has_dbias_batch_sum && all_row_major<A> && all_double_precision<A>);

    /*!
     * \brief Construct a new expression
     * \param a The sub expression
     */
    explicit bias_batch_mean_2d_expr(A a) : base_type(a) {
        //Nothing else to init
    }

    /*!
     * \brief Validate the transposition dimensions
     * \param a The input matrix
     * \þaram c The output matrix
     */
    template <typename C>
    static void check([[maybe_unused]] const A& a, [[maybe_unused]] const C& c) {
        static_assert(etl::dimensions<C>() == 1, "The output of bias_batch_mean_2d is a vector");
        static_assert(etl::dimensions<A>() == 2, "The input of bias_batch_mean_2d is a 2d matrix");

        if constexpr (all_fast<A, C>) {
            static_assert(etl::dim<1, A>() == etl::dim<0, C>(), "Invalid dimensions for bias_batch_mean_2d");
        } else {
            cpp_assert(etl::dim<1>(a) == etl::dim<0>(c), "Invalid dimensions for bias_batch_mean_2d");
        }
    }

    // Assignment functions

    /*!
     * \brief Assign to a matrix of the same storage order
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_2d only supported for ETL expressions");

        auto& a = this->a();

        using T = value_t<A>;

        check(a, lhs);

        [[maybe_unused]] const auto N = etl::dim<0>(a);
        [[maybe_unused]] const auto K = etl::dim<1>(a);

        if constexpr (!Mean && impl::egblas::has_sbias_batch_sum && all_row_major<A> && all_floating<A, L>) {
            auto t1 = smart_forward_gpu(a);
            t1.ensure_gpu_up_to_date();

            lhs.ensure_gpu_allocated();

            impl::egblas::bias_batch_sum(N, K, t1.gpu_memory(), 1, lhs.gpu_memory(), 1);

            lhs.validate_gpu();
            lhs.invalidate_cpu();
        } else if constexpr (Mean && impl::egblas::has_sbias_batch_mean && all_row_major<A> && all_floating<A, L>) {
            auto t1 = smart_forward_gpu(a);
            t1.ensure_gpu_up_to_date();

            lhs.ensure_gpu_allocated();

            impl::egblas::bias_batch_mean(N, K, t1.gpu_memory(), 1, lhs.gpu_memory(), 1);

            lhs.validate_gpu();
            lhs.invalidate_cpu();
        } else if constexpr (!Mean && cudnn_enabled && all_floating<A, L>) {
            impl::cudnn::bias_batch_mean_2d(smart_forward_gpu(a), lhs);
        } else {

            standard_evaluator::pre_assign_rhs(a);

            for (size_t k = 0; k < K; ++k) {
                T mean(0);

                for (size_t b = 0; b < N; ++b) {
                    mean += a(b, k);
                }

                if constexpr (Mean) {
                    lhs(k) = mean / N;
                } else {
                    lhs(k) = mean;
                }
            }
        }
    }

    /*!
     * \brief Add to the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_add_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_2d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        for (size_t k = 0; k < K; ++k) {
            T mean(0);

            for (size_t b = 0; b < N; ++b) {
                mean += a(b, k);
            }

            if constexpr (Mean) {
                lhs(k) += mean / N;
            } else {
                lhs(k) += mean;
            }
        }
    }

    /*!
     * \brief Sub from the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_sub_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_2d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        for (size_t k = 0; k < K; ++k) {
            T mean(0);

            for (size_t b = 0; b < N; ++b) {
                mean += a(b, k);
            }

            if constexpr (Mean) {
                lhs(k) -= mean / N;
            } else {
                lhs(k) -= mean;
            }
        }
    }

    /*!
     * \brief Multiply the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_mul_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_2d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        for (size_t k = 0; k < K; ++k) {
            T mean(0);

            for (size_t b = 0; b < N; ++b) {
                mean += a(b, k);
            }

            if constexpr (Mean) {
                lhs(k) *= mean / N;
            } else {
                lhs(k) *= mean;
            }
        }
    }

    /*!
     * \brief Divide the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_div_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_2d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        for (size_t k = 0; k < K; ++k) {
            T mean(0);

            for (size_t b = 0; b < N; ++b) {
                mean += a(b, k);
            }

            if constexpr (Mean) {
                lhs(k) /= mean / N;
            } else {
                lhs(k) /= mean;
            }
        }
    }

    /*!
     * \brief Modulo the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_mod_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_2d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        for (size_t k = 0; k < K; ++k) {
            T mean(0);

            for (size_t b = 0; b < N; ++b) {
                mean += a(b, k);
            }

            if constexpr (Mean) {
                lhs(k) %= mean / N;
            } else {
                lhs(k) %= mean;
            }
        }
    }

    /*!
     * \brief Print a representation of the expression on the given stream
     * \param os The output stream
     * \param expr The expression to print
     * \return the output stream
     */
    friend std::ostream& operator<<(std::ostream& os, const bias_batch_mean_2d_expr& expr) {
        if (Mean) {
            return os << "bias_batch_mean_2d(" << expr._a << ")";
        } else {
            return os << "bias_batch_sum_2d(" << expr._a << ")";
        }
    }
};

/*!
 * \brief Traits for a transpose expression
 * \tparam A The transposed sub type
 */
template <typename A, bool Mean>
struct etl_traits<etl::bias_batch_mean_2d_expr<A, Mean>> {
    using expr_t     = etl::bias_batch_mean_2d_expr<A, Mean>; ///< The expression type
    using sub_expr_t = std::decay_t<A>;                       ///< The sub expression type
    using sub_traits = etl_traits<sub_expr_t>;                ///< The sub traits
    using value_type = value_t<A>;                            ///< The value type of the expression

    static constexpr bool is_etl         = true;                                 ///< Indicates if the type is an ETL expression
    static constexpr bool is_transformer = false;                                ///< Indicates if the type is a transformer
    static constexpr bool is_view        = false;                                ///< Indicates if the type is a view
    static constexpr bool is_magic_view  = false;                                ///< Indicates if the type is a magic view
    static constexpr bool is_fast        = sub_traits::is_fast;                  ///< Indicates if the expression is fast
    static constexpr bool is_linear      = false;                                ///< Indicates if the expression is linear
    static constexpr bool is_thread_safe = true;                                 ///< Indicates if the expression is thread safe
    static constexpr bool is_value       = false;                                ///< Indicates if the expression is of value type
    static constexpr bool is_direct      = true;                                 ///< Indicates if the expression has direct memory access
    static constexpr bool is_generator   = false;                                ///< Indicates if the expression is a generator
    static constexpr bool is_padded      = false;                                ///< Indicates if the expression is padded
    static constexpr bool is_aligned     = true;                                 ///< Indicates if the expression is padded
    static constexpr bool is_temporary   = true;                                 ///< Indicates if the expression needs a evaluator visitor
    static constexpr order storage_order = sub_traits::storage_order;            ///< The expression's storage order
    static constexpr bool gpu_computable = is_gpu_t<value_type> && cuda_enabled; ///< Indicates if the expression can be computed on GPU

    /*!
     * \brief Indicates if the expression is vectorizable using the
     * given vector mode
     * \tparam V The vector mode
     */
    template <vector_mode_t V>
    static constexpr bool vectorizable = true;

    /*!
     * \brief Returns the DDth dimension of the expression
     * \return the DDth dimension of the expression
     */
    template <size_t DD>
    static constexpr size_t dim() {
        static_assert(DD == 0, "Invalid dimensions access");
        return decay_traits<A>::template dim<1>();
    }

    /*!
     * \brief Returns the dth dimension of the expression
     * \param e The sub expression
     * \param d The dimension to get
     * \return the dth dimension of the expression
     */
    static size_t dim(const expr_t& e, [[maybe_unused]] size_t d) {
        cpp_assert(d == 0, "Invalid dimensions access");

        return etl::dim<1>(e._a);
    }

    /*!
     * \brief Returns the size of the expression
     * \param e The sub expression
     * \return the size of the expression
     */
    static size_t size(const expr_t& e) {
        return etl::dim<1>(e._a);
    }

    /*!
     * \brief Returns the size of the expression
     * \return the size of the expression
     */
    static constexpr size_t size() {
        return decay_traits<A>::template dim<1>();
    }

    /*!
     * \brief Returns the number of dimensions of the expression
     * \return the number of dimensions of the expression
     */
    static constexpr size_t dimensions() {
        return 1;
    }
};

/*!
 * \brief Returns the transpose of the given expression.
 * \param value The expression
 * \return The transpose of the given expression.
 */
template <typename E>
bias_batch_mean_2d_expr<detail::build_type<E>, true> bias_batch_mean_2d(const E& value) {
    static_assert(is_etl_expr<E>, "etl::bias_batch_mean_2d can only be used on ETL expressions");
    static_assert(is_2d<E>, "etl::bias_batch_mean_2d is only defined for 2d input");

    return bias_batch_mean_2d_expr<detail::build_type<E>, true>{value};
}

/*!
 * \brief Returns the transpose of the given expression.
 * \param value The expression
 * \return The transpose of the given expression.
 */
template <typename E>
bias_batch_mean_2d_expr<detail::build_type<E>, false> bias_batch_sum_2d(const E& value) {
    static_assert(is_etl_expr<E>, "etl::bias_batch_sum_2d can only be used on ETL expressions");
    static_assert(is_2d<E>, "etl::bias_batch_sum_2d is only defined for 2d input");

    return bias_batch_mean_2d_expr<detail::build_type<E>, false>{value};
}

} //end of namespace etl
<|endoftext|>


<commit_before>#include <graphics.hpp>
#include <exceptions.hpp>

namespace appbase {
namespace graph {

using namespace appbase::error;

GraphicsManager::GraphicsManager(const GraphicsSettings &settings,
	const SdlWindowPtr &window) :
	m_settings(settings)
{
	// Create renderer
	{
		Uint32 flags = 0;
		if (m_settings.vsync) {
			flags |= SDL_RENDERER_PRESENTVSYNC;
		}
		::SDL_Log("Create HW renderer...");
		m_renderer.reset(::SDL_CreateRenderer(
			window.get(), -1, flags | SDL_RENDERER_ACCELERATED));
		if (m_renderer == nullptr) {
			::SDL_Log("Create SW renderer...");
			m_renderer.reset(::SDL_CreateRenderer(
				window.get(), -1, flags | SDL_RENDERER_SOFTWARE));
		}
		if (m_renderer == nullptr) {
			ThrowLastSdlError<SdlError>();
		}
		::SDL_Log("Create renderer OK");
	}
	// Init SDL_image
	{
		::SDL_Log("Initialize SDL_image...");
		int flags = 0;
		flags |= m_settings.loadEnable.jpg ? IMG_INIT_JPG : 0;
		flags |= m_settings.loadEnable.png ? IMG_INIT_PNG : 0;
		flags |= m_settings.loadEnable.tif ? IMG_INIT_TIF : 0;
		int inited = IMG_Init(flags);
		if ((inited & flags) != flags) {
			throw SdlImageError("SDL_image init failed");
		}
		m_sdl_image.reset(this);
		::SDL_Log("Initialize SDL_image OK");
	}
	// Init SDL_ttf
	{
		::SDL_Log("Initialize SDL_ttf...");
		if (TTF_Init() < 0) {
			ThrowLastSdlTtfError<SdlTtfError>();
		}
		m_sdl_ttf.reset(this);
		::SDL_Log("Initialize SDL_ttf OK");
	}
}

void GraphicsManager::Clear()
{
	if (::SDL_SetRenderDrawColor(m_renderer.get(),
		m_settings.clear.r, m_settings.clear.g, m_settings.clear.b,
		m_settings.clear.a) < 0) {
		ThrowLastSdlError<SdlError>();
	}
	if (::SDL_RenderClear(m_renderer.get()) < 0) {
		ThrowLastSdlError<SdlError>();
	}
}

void GraphicsManager::Present()
{
	::SDL_RenderPresent(m_renderer.get());
}

void GraphicsManager::DrawTexture(const SdlTexturePtr &tex,
	int x, int y)
{
	auto size = GetTextureSize(tex);
	SDL_Rect dst;
	dst.x = x;
	dst.y = y;
	dst.w = std::get<0>(size);
	dst.h = std::get<1>(size);
	::SDL_RenderCopy(m_renderer.get(), tex.get(), nullptr, &dst);
}

SdlSurfacePtr GraphicsManager::LoadImage(const std::string &path)
{
	::SDL_Log("Load image: %s", path.c_str());
	SdlSurfacePtr surface(IMG_Load(path.c_str()));
	if (surface == nullptr) {
		ThrowLastSdlImageError<SdlImageError>();
	}
	return surface;
}

SdlTexturePtr GraphicsManager::CreateTexture(const SdlSurfacePtr &surface)
{
	SdlTexturePtr texture(SDL_CreateTextureFromSurface(
		m_renderer.get(), surface.get()));
	if (texture == nullptr) {
		ThrowLastSdlImageError<SdlImageError>();
	}
	return texture;
}

std::tuple<int, int> GraphicsManager::GetTextureSize(const SdlTexturePtr &tex)
{
	int w, h;
	if(::SDL_QueryTexture(tex.get(), nullptr, nullptr, &w, &h) < 0) {
		ThrowLastSdlError<SdlError>();
	}
	return std::make_tuple(w, h);
}

SdlFontPtr GraphicsManager::LoadFont(const std::string &path, int hsize)
{
	::SDL_Log("Load font: %s", path.c_str());
	SdlFontPtr font(::TTF_OpenFont(path.c_str(), hsize));
	if (font == nullptr) {
		ThrowLastSdlTtfError<SdlTtfError>();
	}
	return font;
}

SdlSurfacePtr GraphicsManager::CreateFontImage(const SdlFontPtr &font,
	char32_t codepoint)
{
	// white
	SDL_Color color = { 255, 255, 255, 255 };
	// codepoint to utf-16 string
	std::array<Uint16, 3> str;
	if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
		str[0] = codepoint;
		str[1] = 0;
	}
	// surrogate pair seems not to be supported...
	/*
	else if (codepoint >= 0x10000 && codepoint <= 0x10FFFF) {
		auto c = static_cast<uint32_t>(codepoint);
		uint32_t w = ((codepoint & 0x1F00) >> 16) - 1;
		uint32_t x = (codepoint & 0xFF);
		uint32_t xl = (x & 0x3FF);
		uint32_t xh = ((x >> 10) & 0x3F);
		str[0] = 0b1101100000000000 | (w << 6) | xh;
		str[1] = 0b1101110000000000 | xl;
		str[2] = 0;
	}
	*/
	else {
		str[0] = '?';
		str[1] = 0;
	}
	SdlSurfacePtr surface(::TTF_RenderUNICODE_Solid(
		font.get(), str.data(), color));
	if (surface == nullptr) {
		ThrowLastSdlTtfError<SdlTtfError>();
	}
	return surface;
}

}
}
<commit_msg>Fix Windows build errors and warnings<commit_after>#include <graphics.hpp>
#include <exceptions.hpp>
#include <array>

namespace appbase {
namespace graph {

using namespace appbase::error;

GraphicsManager::GraphicsManager(const GraphicsSettings &settings,
	const SdlWindowPtr &window) :
	m_settings(settings)
{
	// Create renderer
	{
		Uint32 flags = 0;
		if (m_settings.vsync) {
			flags |= SDL_RENDERER_PRESENTVSYNC;
		}
		::SDL_Log("Create HW renderer...");
		m_renderer.reset(::SDL_CreateRenderer(
			window.get(), -1, flags | SDL_RENDERER_ACCELERATED));
		if (m_renderer == nullptr) {
			::SDL_Log("Create SW renderer...");
			m_renderer.reset(::SDL_CreateRenderer(
				window.get(), -1, flags | SDL_RENDERER_SOFTWARE));
		}
		if (m_renderer == nullptr) {
			ThrowLastSdlError<SdlError>();
		}
		::SDL_Log("Create renderer OK");
	}
	// Init SDL_image
	{
		::SDL_Log("Initialize SDL_image...");
		int flags = 0;
		flags |= m_settings.loadEnable.jpg ? IMG_INIT_JPG : 0;
		flags |= m_settings.loadEnable.png ? IMG_INIT_PNG : 0;
		flags |= m_settings.loadEnable.tif ? IMG_INIT_TIF : 0;
		int inited = IMG_Init(flags);
		if ((inited & flags) != flags) {
			throw SdlImageError("SDL_image init failed");
		}
		m_sdl_image.reset(this);
		::SDL_Log("Initialize SDL_image OK");
	}
	// Init SDL_ttf
	{
		::SDL_Log("Initialize SDL_ttf...");
		if (TTF_Init() < 0) {
			ThrowLastSdlTtfError<SdlTtfError>();
		}
		m_sdl_ttf.reset(this);
		::SDL_Log("Initialize SDL_ttf OK");
	}
}

void GraphicsManager::Clear()
{
	if (::SDL_SetRenderDrawColor(m_renderer.get(),
		m_settings.clear.r, m_settings.clear.g, m_settings.clear.b,
		m_settings.clear.a) < 0) {
		ThrowLastSdlError<SdlError>();
	}
	if (::SDL_RenderClear(m_renderer.get()) < 0) {
		ThrowLastSdlError<SdlError>();
	}
}

void GraphicsManager::Present()
{
	::SDL_RenderPresent(m_renderer.get());
}

void GraphicsManager::DrawTexture(const SdlTexturePtr &tex,
	int x, int y)
{
	auto size = GetTextureSize(tex);
	SDL_Rect dst;
	dst.x = x;
	dst.y = y;
	dst.w = std::get<0>(size);
	dst.h = std::get<1>(size);
	::SDL_RenderCopy(m_renderer.get(), tex.get(), nullptr, &dst);
}

SdlSurfacePtr GraphicsManager::LoadImage(const std::string &path)
{
	::SDL_Log("Load image: %s", path.c_str());
	SdlSurfacePtr surface(IMG_Load(path.c_str()));
	if (surface == nullptr) {
		ThrowLastSdlImageError<SdlImageError>();
	}
	return surface;
}

SdlTexturePtr GraphicsManager::CreateTexture(const SdlSurfacePtr &surface)
{
	SdlTexturePtr texture(SDL_CreateTextureFromSurface(
		m_renderer.get(), surface.get()));
	if (texture == nullptr) {
		ThrowLastSdlImageError<SdlImageError>();
	}
	return texture;
}

std::tuple<int, int> GraphicsManager::GetTextureSize(const SdlTexturePtr &tex)
{
	int w, h;
	if(::SDL_QueryTexture(tex.get(), nullptr, nullptr, &w, &h) < 0) {
		ThrowLastSdlError<SdlError>();
	}
	return std::make_tuple(w, h);
}

SdlFontPtr GraphicsManager::LoadFont(const std::string &path, int hsize)
{
	::SDL_Log("Load font: %s", path.c_str());
	SdlFontPtr font(::TTF_OpenFont(path.c_str(), hsize));
	if (font == nullptr) {
		ThrowLastSdlTtfError<SdlTtfError>();
	}
	return font;
}

SdlSurfacePtr GraphicsManager::CreateFontImage(const SdlFontPtr &font,
	char32_t codepoint)
{
	// white
	SDL_Color color = { 255, 255, 255, 255 };
	// codepoint to utf-16 string
	std::array<Uint16, 3> str;
	if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
		str[0] = static_cast<Uint16>(codepoint);
		str[1] = 0;
	}
	// surrogate pair seems not to be supported...
	/*
	else if (codepoint >= 0x10000 && codepoint <= 0x10FFFF) {
		auto c = static_cast<uint32_t>(codepoint);
		uint32_t w = ((codepoint & 0x1F00) >> 16) - 1;
		uint32_t x = (codepoint & 0xFF);
		uint32_t xl = (x & 0x3FF);
		uint32_t xh = ((x >> 10) & 0x3F);
		str[0] = 0b1101100000000000 | (w << 6) | xh;
		str[1] = 0b1101110000000000 | xl;
		str[2] = 0;
	}
	*/
	else {
		str[0] = '?';
		str[1] = 0;
	}
	SdlSurfacePtr surface(::TTF_RenderUNICODE_Solid(
		font.get(), str.data(), color));
	if (surface == nullptr) {
		ThrowLastSdlTtfError<SdlTtfError>();
	}
	return surface;
}

}
}
<|endoftext|>


<commit_before>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2008 Aristid Breitkreuz, Ruediger Sonderfeld

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#ifndef FLUSSPFERD_SPIDERMONKEY_FUNCTION_HPP
#define FLUSSPFERD_SPIDERMONKEY_FUNCTION_HPP

typedef struct JSFunction JSFunction;

namespace flusspferd {

class object;

namespace Impl {
  class function_impl {
    JSFunction *func;

  protected:
    JSFunction *get() { return func; }
    JSFunction *get_const() const { return func; }
    void set(JSFunction *f) { func = f; }

    function_impl() : func(0x0) { }
    function_impl(JSFunction *f) : func(f) { }

    object get_object();

    friend JSFunction *get_function(function_impl &f);
    friend function_impl wrap_function(JSFunction *f);
  };

  inline JSFunction *get_function(function_impl &f) {
    return f.get();
  }

  inline function_impl wrap_function(JSFunction *f) {
    return function_impl(f);
  }
}}

#endif /* FLUSSPFERD_SPIDERMONKEY_FUNCTION_HPP */
<commit_msg>Core: more style<commit_after>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2008 Aristid Breitkreuz, Ruediger Sonderfeld

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#ifndef FLUSSPFERD_SPIDERMONKEY_FUNCTION_HPP
#define FLUSSPFERD_SPIDERMONKEY_FUNCTION_HPP

#include <js/jsapi.h>

namespace flusspferd {

class object;

namespace Impl {

class function_impl {
  JSFunction *func;

protected:
  JSFunction *get() { return func; }
  JSFunction *get_const() const { return func; }
  void set(JSFunction *f) { func = f; }

  function_impl() : func(0x0) { }
  function_impl(JSFunction *f) : func(f) { }

  object get_object();

  friend JSFunction *get_function(function_impl &f);
  friend function_impl wrap_function(JSFunction *f);
};

inline JSFunction *get_function(function_impl &f) {
  return f.get();
}

inline function_impl wrap_function(JSFunction *f) {
  return function_impl(f);
}

}}

#endif /* FLUSSPFERD_SPIDERMONKEY_FUNCTION_HPP */
<|endoftext|>


<commit_before>/*
 * xtensor-fftw
 * Copyright (c) 2017, Patrick Bos
 * Distributed under the terms of the BSD 3-Clause License.
 *
 * The full license is in the file LICENSE, distributed with this software.
 */

#ifndef XTENSOR_FFTW_CONFIG_HPP
#define XTENSOR_FFTW_CONFIG_HPP

#define XTENSOR_FFTW_VERSION_MAJOR 0
#define XTENSOR_FFTW_VERSION_MINOR 2
#define XTENSOR_FFTW_VERSION_PATCH 3

#endif //XTENSOR_FFTW_CONFIG_HPP
<commit_msg>Release 0.2.4<commit_after>/*
 * xtensor-fftw
 * Copyright (c) 2017, Patrick Bos
 * Distributed under the terms of the BSD 3-Clause License.
 *
 * The full license is in the file LICENSE, distributed with this software.
 */

#ifndef XTENSOR_FFTW_CONFIG_HPP
#define XTENSOR_FFTW_CONFIG_HPP

#define XTENSOR_FFTW_VERSION_MAJOR 0
#define XTENSOR_FFTW_VERSION_MINOR 2
#define XTENSOR_FFTW_VERSION_PATCH 4

#endif //XTENSOR_FFTW_CONFIG_HPP
<|endoftext|>


<commit_before><commit_msg>Forgot to increment the iterator.<commit_after><|endoftext|>


<commit_before><commit_msg>fix tests<commit_after><|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include <QtGui/QBoxLayout>
#include <QtGui/QTreeView>
#include <QtGui/QHeaderView>
#include <model.h>

#include "navigatorwidget.h"
#include "navigatorview.h"

#include <utils/fileutils.h>

namespace QmlDesigner {

NavigatorWidget::NavigatorWidget(NavigatorView *view) :
        QFrame(),
        m_treeView(new NavigatorTreeView),
        m_navigatorView(view)
{
    m_treeView->setDragEnabled(true);
    m_treeView->setAcceptDrops(true);
    m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
    m_treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_treeView->header()->setStretchLastSection(false);
    m_treeView->setDefaultDropAction(Qt::LinkAction);
    m_treeView->setFocusPolicy(Qt::NoFocus);
    m_treeView->setHeaderHidden(true);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->setSpacing(0);
    layout->setMargin(0);
    layout->addWidget(m_treeView);

    setLayout(layout);

    setWindowTitle(tr("Navigator", "Title of navigator view"));

    setStyleSheet(QLatin1String(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css")));
    m_treeView->setStyleSheet(
            QLatin1String(Utils::FileReader::fetchQrc(":/qmldesigner/scrollbar.css")));
}

NavigatorWidget::~NavigatorWidget()
{

}

void NavigatorWidget::setTreeModel(QAbstractItemModel* model)
{
    m_treeView->setModel(model);
}

QList<QToolButton *> NavigatorWidget::createToolBarWidgets()
{
    QList<QToolButton *> buttons;

    buttons << new QToolButton();
    buttons.last()->setIcon(QIcon(":/navigator/icon/arrowleft.png"));
    buttons.last()->setToolTip(tr("Become first sibling of parent (CTRL + Left)"));
    buttons.last()->setShortcut(QKeySequence(Qt::Key_Left | Qt::CTRL));
    connect(buttons.last(), SIGNAL(clicked()), this, SIGNAL(leftButtonClicked()));
    buttons << new QToolButton();
    buttons.last()->setIcon(QIcon(":/navigator/icon/arrowright.png"));
    buttons.last()->setToolTip(tr("Become child of first silbing (CTRL + Right)"));
    buttons.last()->setShortcut(QKeySequence(Qt::Key_Right | Qt::CTRL));
    connect(buttons.last(), SIGNAL(clicked()), this, SIGNAL(rightButtonClicked()));

    buttons << new QToolButton();
    buttons.last()->setIcon(QIcon(":/navigator/icon/arrowdown.png"));
    buttons.last()->setToolTip(tr("Move down (CTRL + Down)"));
    buttons.last()->setShortcut(QKeySequence(Qt::Key_Down | Qt::CTRL));
    connect(buttons.last(), SIGNAL(clicked()), this, SIGNAL(downButtonClicked()));

    buttons << new QToolButton();
    buttons.last()->setIcon(QIcon(":/navigator/icon/arrowup.png"));
    buttons.last()->setToolTip(tr("Move up (CTRL + Up)"));
    buttons.last()->setShortcut(QKeySequence(Qt::Key_Up | Qt::CTRL));
    connect(buttons.last(), SIGNAL(clicked()), this, SIGNAL(upButtonClicked()));

    return buttons;
}

QString NavigatorWidget::contextHelpId() const
{
    if (!navigatorView())
        return QString();

    QList<ModelNode> nodes = navigatorView()->selectedModelNodes();
    QString helpId;
    if (!nodes.isEmpty()) {
        helpId = nodes.first().type();
        helpId.replace("QtQuick", "QML");
    }

    return helpId;
}

NavigatorView *NavigatorWidget::navigatorView() const
{
    return m_navigatorView.data();
}

}
<commit_msg>QmlDesigner.navigatorWidget: changing focus policy<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include <QtGui/QBoxLayout>
#include <QtGui/QTreeView>
#include <QtGui/QHeaderView>
#include <model.h>

#include "navigatorwidget.h"
#include "navigatorview.h"

#include <utils/fileutils.h>

namespace QmlDesigner {

NavigatorWidget::NavigatorWidget(NavigatorView *view) :
        QFrame(),
        m_treeView(new NavigatorTreeView),
        m_navigatorView(view)
{
    m_treeView->setDragEnabled(true);
    m_treeView->setAcceptDrops(true);
    m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
    m_treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_treeView->header()->setStretchLastSection(false);
    m_treeView->setDefaultDropAction(Qt::LinkAction);
    m_treeView->setHeaderHidden(true);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->setSpacing(0);
    layout->setMargin(0);
    layout->addWidget(m_treeView);

    setLayout(layout);

    setWindowTitle(tr("Navigator", "Title of navigator view"));

    setStyleSheet(QLatin1String(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css")));
    m_treeView->setStyleSheet(
            QLatin1String(Utils::FileReader::fetchQrc(":/qmldesigner/scrollbar.css")));
}

NavigatorWidget::~NavigatorWidget()
{

}

void NavigatorWidget::setTreeModel(QAbstractItemModel* model)
{
    m_treeView->setModel(model);
}

QList<QToolButton *> NavigatorWidget::createToolBarWidgets()
{
    QList<QToolButton *> buttons;

    buttons << new QToolButton();
    buttons.last()->setIcon(QIcon(":/navigator/icon/arrowleft.png"));
    buttons.last()->setToolTip(tr("Become first sibling of parent (CTRL + Left)"));
    buttons.last()->setShortcut(QKeySequence(Qt::Key_Left | Qt::CTRL));
    connect(buttons.last(), SIGNAL(clicked()), this, SIGNAL(leftButtonClicked()));
    buttons << new QToolButton();
    buttons.last()->setIcon(QIcon(":/navigator/icon/arrowright.png"));
    buttons.last()->setToolTip(tr("Become child of first silbing (CTRL + Right)"));
    buttons.last()->setShortcut(QKeySequence(Qt::Key_Right | Qt::CTRL));
    connect(buttons.last(), SIGNAL(clicked()), this, SIGNAL(rightButtonClicked()));

    buttons << new QToolButton();
    buttons.last()->setIcon(QIcon(":/navigator/icon/arrowdown.png"));
    buttons.last()->setToolTip(tr("Move down (CTRL + Down)"));
    buttons.last()->setShortcut(QKeySequence(Qt::Key_Down | Qt::CTRL));
    connect(buttons.last(), SIGNAL(clicked()), this, SIGNAL(downButtonClicked()));

    buttons << new QToolButton();
    buttons.last()->setIcon(QIcon(":/navigator/icon/arrowup.png"));
    buttons.last()->setToolTip(tr("Move up (CTRL + Up)"));
    buttons.last()->setShortcut(QKeySequence(Qt::Key_Up | Qt::CTRL));
    connect(buttons.last(), SIGNAL(clicked()), this, SIGNAL(upButtonClicked()));

    return buttons;
}

QString NavigatorWidget::contextHelpId() const
{
    if (!navigatorView())
        return QString();

    QList<ModelNode> nodes = navigatorView()->selectedModelNodes();
    QString helpId;
    if (!nodes.isEmpty()) {
        helpId = nodes.first().type();
        helpId.replace("QtQuick", "QML");
    }

    return helpId;
}

NavigatorView *NavigatorWidget::navigatorView() const
{
    return m_navigatorView.data();
}

}
<|endoftext|>


<commit_before><commit_msg>correct UTF8 handling for FILTERXML, fdo#72427<commit_after><|endoftext|>


<commit_before>/*
 *  Copyright 2008-2013 NVIDIA Corporation
 *
 *  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.
 */

#pragma once

#include <thrust/system/cuda/detail/bulk/detail/config.hpp>
#include <thrust/system/cuda/detail/bulk/malloc.hpp>
#include <thrust/system/cuda/detail/bulk/execution_policy.hpp>
#include <thrust/system/cuda/detail/bulk/detail/tuple_transform.hpp>
#include <thrust/system/cuda/detail/bulk/detail/closure.hpp>

#include <thrust/detail/type_traits.h>

BULK_NAMESPACE_PREFIX
namespace bulk
{
namespace detail
{

template<typename ExecutionGroup, typename Closure>
class task_base
{
  public:
    typedef ExecutionGroup group_type;
    typedef Closure        closure_type;

    __host__ __device__
    task_base(group_type g, closure_type c)
      : c(c), g(g)
    {}

  protected:
    __host__ __device__
    static void substitute_placeholders_and_execute(group_type &g, closure_type &c)
    {
      // substitute placeholders with this_group
      substituted_arguments_type new_args = substitute_placeholders(g, c.arguments());

      // create a new closure with the new arguments
      closure<typename closure_type::function_type, substituted_arguments_type> new_c(c.function(), new_args);

      // execute the new closure
      new_c();
    }

    closure_type c;
    group_type g;

  private:
    template<typename T>
    struct substitutor_result
      : thrust::detail::eval_if<
          bulk::detail::is_cursor<T>::value,
          cursor_result<T,ExecutionGroup>,
          thrust::detail::identity_<T>
        >
    {};

    typedef typename bulk::detail::tuple_meta_transform<
      typename closure_type::arguments_type,
      substitutor_result
    >::type substituted_arguments_type;

    struct substitutor
    {
      group_type &g;

      __device__
      substitutor(group_type &g)
        : g(g)
      {}

      template<unsigned int depth>
      __device__
      typename bulk::detail::cursor_result<cursor<depth>,group_type>::type
      operator()(cursor<depth> c) const
      {
        return c.get(g);
      }

      template<typename T>
      __device__
      T &operator()(T &x) const
      {
        return x;
      }
    };

    __host__ __device__
    static substituted_arguments_type substitute_placeholders(group_type &g, typename closure_type::arguments_type args)
    {
      return bulk::detail::tuple_host_device_transform<substitutor_result>(args, substitutor(g));
    }
};

template<std::size_t blocksize, std::size_t grainsize>
struct cuda_block
{
  typedef concurrent_group<agent<grainsize>, blocksize> type;
};

template<std::size_t gridsize, std::size_t blocksize, std::size_t grainsize>
struct cuda_grid
{
  typedef parallel_group<
    typename cuda_block<blocksize,grainsize>::type
  > type;
};

template<typename Group, typename Closure> class cuda_task;

template<typename Grid>
struct grid_maker
{
  __host__ __device__
  static Grid make(typename Grid::size_type     size,
                   typename Grid::agent_type    block,
                   typename Grid::size_type     index)
  {
    return Grid(block, index);
  }
};

template<typename Block>
struct grid_maker<parallel_group<Block,dynamic_group_size> >
{
  __host__ __device__
  static parallel_group<Block,dynamic_group_size> make(typename parallel_group<Block,dynamic_group_size>::size_type size,
                                                       Block block,
                                                       typename parallel_group<Block,dynamic_group_size>::size_type index)
  {
    return parallel_group<Block,dynamic_group_size>(size, block, index);
  }
};

template<typename Block>
struct block_maker
{
  __host__ __device__
  static Block make(typename Block::size_type     size,
                    typename Block::size_type     heap_size,
                    typename Block::agent_type    thread,
                    typename Block::size_type     index)
  {
    return Block(heap_size, thread, index);
  }
};

template<typename Thread>
struct block_maker<concurrent_group<Thread,dynamic_group_size> >
{
  __host__ __device__
  static concurrent_group<Thread,dynamic_group_size> make(typename concurrent_group<Thread,dynamic_group_size>::size_type size,
                                                          typename concurrent_group<Thread,dynamic_group_size>::size_type heap_size,
                                                          Thread thread,
                                                          typename concurrent_group<Thread,dynamic_group_size>::size_type index)
  {
    return concurrent_group<Thread,dynamic_group_size>(size, heap_size, thread, index);
  }
};

template<typename Grid>
__host__ __device__
Grid make_grid(typename Grid::size_type size, typename Grid::agent_type block, typename Grid::size_type index = invalid_index)
{
  return grid_maker<Grid>::make(size, block, index);
}

template<typename Block>
__host__ __device__
Block make_block(typename Block::size_type size, typename Block::size_type heap_size, typename Block::agent_type thread = typename Block::agent_type(), typename Block::size_type index = invalid_index)
{
  return block_maker<Block>::make(size, heap_size, thread, index);
}

// specialize cuda_task for a CUDA grid
template<std::size_t gridsize, std::size_t blocksize, std::size_t grainsize, typename Closure>
class cuda_task<
  parallel_group<
    concurrent_group<
      agent<grainsize>,
      blocksize
    >,
    gridsize
  >,
  Closure
> : public task_base<typename cuda_grid<gridsize,blocksize,grainsize>::type,Closure>
{
  private:
    typedef task_base<typename cuda_grid<gridsize,blocksize,grainsize>::type,Closure> super_t;

  public:
    typedef typename super_t::group_type    grid_type;
    typedef typename grid_type::agent_type  block_type;
    typedef typename block_type::agent_type thread_type;
    typedef typename super_t::closure_type  closure_type;
    typedef typename grid_type::size_type   size_type;

  private:
    size_type block_offset;

  public:

    __host__ __device__
    cuda_task(grid_type g, closure_type c, size_type offset)
      : super_t(g,c),
        block_offset(offset)
    {}

    __device__
    void operator()()
    {
      // guard use of CUDA built-ins from foreign compilers
#ifdef __CUDA_ARCH__
      // instantiate a view of this grid
      grid_type this_grid =
        make_grid<grid_type>(
          super_t::g.size(),
          make_block<block_type>(
            blockDim.x,
            super_t::g.this_exec.heap_size(),
            thread_type(threadIdx.x),
            block_offset + blockIdx.x
          ),
          0
      );

#if __CUDA_ARCH__ >= 200
      // initialize shared storage
      if(this_grid.this_exec.this_exec.index() == 0)
      {
        bulk::detail::init_on_chip_malloc(this_grid.this_exec.heap_size());
      }
      this_grid.this_exec.wait();
#endif

      substitute_placeholders_and_execute(this_grid, super_t::c);
#endif
    } // end operator()
}; // end cuda_task

// specialize cuda_task for a single CUDA block
template<std::size_t blocksize, std::size_t grainsize, typename Closure>
class cuda_task<
  concurrent_group<
    agent<grainsize>,
    blocksize
  >,
  Closure
> : public task_base<typename cuda_block<blocksize,grainsize>::type,Closure>
{
  private:
    typedef task_base<typename cuda_block<blocksize,grainsize>::type,Closure> super_t;

  public:
    typedef typename super_t::group_type    block_type;
    typedef typename block_type::agent_type thread_type;
    typedef typename super_t::closure_type  closure_type;
    typedef typename block_type::size_type  size_type;

  public:
    __host__ __device__
    cuda_task(block_type b, closure_type c)
      : super_t(b,c)
    {}

    __device__
    void operator()()
    {
      // guard use of CUDA built-ins from foreign compilers
#ifdef __CUDA_ARCH__
      // instantiate a view of this block
      block_type this_block =
        make_block<block_type>(
          blockDim.x,
          super_t::g.heap_size(),
          thread_type(threadIdx.x),
          0
        );

#if __CUDA_ARCH__ >= 200
      // initialize shared storage
      if(this_block.this_exec.index() == 0)
      {
        bulk::detail::init_on_chip_malloc(this_block.heap_size());
      }
      this_block.wait();
#endif

      substitute_placeholders_and_execute(this_block, super_t::c);
#endif
    } // end operator()
}; // end cuda_task

// specialize cuda_task for a single big parallel group
template<std::size_t groupsize, std::size_t grainsize, typename Closure>
class cuda_task<parallel_group<agent<grainsize>,groupsize>,Closure>
  : public task_base<parallel_group<agent<grainsize>,groupsize>,Closure>
{
  private:
    typedef task_base<parallel_group<agent<grainsize>,groupsize>,Closure> super_t;

  public:
    typedef typename super_t::closure_type closure_type;
    typedef typename super_t::group_type   group_type;

    __host__ __device__
    cuda_task(group_type g, closure_type c)
      : super_t(g,c)
    {}

    __device__
    void operator()()
    {
      // guard use of CUDA built-ins from foreign compilers
#ifdef __CUDA_ARCH__
      const size_t grid_size = gridDim.x * blockDim.x;

      for(size_t offset = blockDim.x * blockIdx.x; offset < super_t::g.size(); offset += grid_size)
      {
        typename group_type::size_type tid = offset + threadIdx.x;

        if(tid < super_t::g.size())
        {
          // instantiate a view of the exec group
          parallel_group<agent<grainsize>,groupsize> this_group(
            1,
            agent<grainsize>(tid),
            0
          );

          substitute_placeholders_and_execute(this_group, super_t::c);
        } // end if
      } // end for
#endif
    } // end operator()
}; // end cuda_task

} // end detail
} // end bulk
BULK_NAMESPACE_SUFFIX

<commit_msg>Eliminate a couple of registers from cuda_task<commit_after>/*
 *  Copyright 2008-2013 NVIDIA Corporation
 *
 *  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.
 */

#pragma once

#include <thrust/system/cuda/detail/bulk/detail/config.hpp>
#include <thrust/system/cuda/detail/bulk/malloc.hpp>
#include <thrust/system/cuda/detail/bulk/execution_policy.hpp>
#include <thrust/system/cuda/detail/bulk/detail/tuple_transform.hpp>
#include <thrust/system/cuda/detail/bulk/detail/closure.hpp>

#include <thrust/detail/type_traits.h>

BULK_NAMESPACE_PREFIX
namespace bulk
{
namespace detail
{

template<typename ExecutionGroup, typename Closure>
class task_base
{
  public:
    typedef ExecutionGroup group_type;
    typedef Closure        closure_type;

    __host__ __device__
    task_base(group_type g, closure_type c)
      : c(c), g(g)
    {}

  protected:
    __host__ __device__
    static void substitute_placeholders_and_execute(group_type &g, closure_type &c)
    {
      // substitute placeholders with this_group
      substituted_arguments_type new_args = substitute_placeholders(g, c.arguments());

      // create a new closure with the new arguments
      closure<typename closure_type::function_type, substituted_arguments_type> new_c(c.function(), new_args);

      // execute the new closure
      new_c();
    }

    closure_type c;
    group_type g;

  private:
    template<typename T>
    struct substitutor_result
      : thrust::detail::eval_if<
          bulk::detail::is_cursor<T>::value,
          cursor_result<T,ExecutionGroup>,
          thrust::detail::identity_<T>
        >
    {};

    typedef typename bulk::detail::tuple_meta_transform<
      typename closure_type::arguments_type,
      substitutor_result
    >::type substituted_arguments_type;

    struct substitutor
    {
      group_type &g;

      __device__
      substitutor(group_type &g)
        : g(g)
      {}

      template<unsigned int depth>
      __device__
      typename bulk::detail::cursor_result<cursor<depth>,group_type>::type
      operator()(cursor<depth> c) const
      {
        return c.get(g);
      }

      template<typename T>
      __device__
      T &operator()(T &x) const
      {
        return x;
      }
    };

    __host__ __device__
    static substituted_arguments_type substitute_placeholders(group_type &g, typename closure_type::arguments_type args)
    {
      return bulk::detail::tuple_host_device_transform<substitutor_result>(args, substitutor(g));
    }
};

template<std::size_t blocksize, std::size_t grainsize>
struct cuda_block
{
  typedef concurrent_group<agent<grainsize>, blocksize> type;
};

template<std::size_t gridsize, std::size_t blocksize, std::size_t grainsize>
struct cuda_grid
{
  typedef parallel_group<
    typename cuda_block<blocksize,grainsize>::type
  > type;
};

template<typename Group, typename Closure> class cuda_task;

template<typename Grid>
struct grid_maker
{
  __host__ __device__
  static Grid make(typename Grid::size_type     size,
                   typename Grid::agent_type    block,
                   typename Grid::size_type     index)
  {
    return Grid(block, index);
  }
};

template<typename Block>
struct grid_maker<parallel_group<Block,dynamic_group_size> >
{
  __host__ __device__
  static parallel_group<Block,dynamic_group_size> make(typename parallel_group<Block,dynamic_group_size>::size_type size,
                                                       Block block,
                                                       typename parallel_group<Block,dynamic_group_size>::size_type index)
  {
    return parallel_group<Block,dynamic_group_size>(size, block, index);
  }
};

template<typename Block>
struct block_maker
{
  __host__ __device__
  static Block make(typename Block::size_type     size,
                    typename Block::size_type     heap_size,
                    typename Block::agent_type    thread,
                    typename Block::size_type     index)
  {
    return Block(heap_size, thread, index);
  }
};

template<typename Thread>
struct block_maker<concurrent_group<Thread,dynamic_group_size> >
{
  __host__ __device__
  static concurrent_group<Thread,dynamic_group_size> make(typename concurrent_group<Thread,dynamic_group_size>::size_type size,
                                                          typename concurrent_group<Thread,dynamic_group_size>::size_type heap_size,
                                                          Thread thread,
                                                          typename concurrent_group<Thread,dynamic_group_size>::size_type index)
  {
    return concurrent_group<Thread,dynamic_group_size>(size, heap_size, thread, index);
  }
};

template<typename Grid>
__host__ __device__
Grid make_grid(typename Grid::size_type size, typename Grid::agent_type block, typename Grid::size_type index = invalid_index)
{
  return grid_maker<Grid>::make(size, block, index);
}

template<typename Block>
__host__ __device__
Block make_block(typename Block::size_type size, typename Block::size_type heap_size, typename Block::agent_type thread = typename Block::agent_type(), typename Block::size_type index = invalid_index)
{
  return block_maker<Block>::make(size, heap_size, thread, index);
}

// specialize cuda_task for a CUDA grid
template<std::size_t gridsize, std::size_t blocksize, std::size_t grainsize, typename Closure>
class cuda_task<
  parallel_group<
    concurrent_group<
      agent<grainsize>,
      blocksize
    >,
    gridsize
  >,
  Closure
> : public task_base<typename cuda_grid<gridsize,blocksize,grainsize>::type,Closure>
{
  private:
    typedef task_base<typename cuda_grid<gridsize,blocksize,grainsize>::type,Closure> super_t;

  public:
    typedef typename super_t::group_type    grid_type;
    typedef typename grid_type::agent_type  block_type;
    typedef typename block_type::agent_type thread_type;
    typedef typename super_t::closure_type  closure_type;
    typedef typename grid_type::size_type   size_type;

  private:
    size_type block_offset;

  public:

    __host__ __device__
    cuda_task(grid_type g, closure_type c, size_type offset)
      : super_t(g,c),
        block_offset(offset)
    {}

    __device__
    void operator()()
    {
      // guard use of CUDA built-ins from foreign compilers
#ifdef __CUDA_ARCH__
      // instantiate a view of this grid
      grid_type this_grid =
        make_grid<grid_type>(
          super_t::g.size(),
          make_block<block_type>(
            blockDim.x,
            super_t::g.this_exec.heap_size(),
            thread_type(threadIdx.x),
            block_offset + blockIdx.x
          ),
          0
      );

#if __CUDA_ARCH__ >= 200
      // initialize shared storage
      if(this_grid.this_exec.this_exec.index() == 0)
      {
        bulk::detail::init_on_chip_malloc(this_grid.this_exec.heap_size());
      }
      this_grid.this_exec.wait();
#endif

      substitute_placeholders_and_execute(this_grid, super_t::c);
#endif
    } // end operator()
}; // end cuda_task

// specialize cuda_task for a single CUDA block
template<std::size_t blocksize, std::size_t grainsize, typename Closure>
class cuda_task<
  concurrent_group<
    agent<grainsize>,
    blocksize
  >,
  Closure
> : public task_base<typename cuda_block<blocksize,grainsize>::type,Closure>
{
  private:
    typedef task_base<typename cuda_block<blocksize,grainsize>::type,Closure> super_t;

  public:
    typedef typename super_t::group_type    block_type;
    typedef typename block_type::agent_type thread_type;
    typedef typename super_t::closure_type  closure_type;
    typedef typename block_type::size_type  size_type;

  public:
    __host__ __device__
    cuda_task(block_type b, closure_type c)
      : super_t(b,c)
    {}

    __device__
    void operator()()
    {
      // guard use of CUDA built-ins from foreign compilers
#ifdef __CUDA_ARCH__
      // instantiate a view of this block
      block_type this_block =
        make_block<block_type>(
          blockDim.x,
          super_t::g.heap_size(),
          thread_type(threadIdx.x),
          0
        );

#if __CUDA_ARCH__ >= 200
      // initialize shared storage
      if(this_block.this_exec.index() == 0)
      {
        bulk::detail::init_on_chip_malloc(this_block.heap_size());
      }
      this_block.wait();
#endif

      substitute_placeholders_and_execute(this_block, super_t::c);
#endif
    } // end operator()
}; // end cuda_task

// specialize cuda_task for a single big parallel group
template<std::size_t groupsize, std::size_t grainsize, typename Closure>
class cuda_task<parallel_group<agent<grainsize>,groupsize>,Closure>
  : public task_base<parallel_group<agent<grainsize>,groupsize>,Closure>
{
  private:
    typedef task_base<parallel_group<agent<grainsize>,groupsize>,Closure> super_t;

  public:
    typedef typename super_t::closure_type closure_type;
    typedef typename super_t::group_type   group_type;

    __host__ __device__
    cuda_task(group_type g, closure_type c)
      : super_t(g,c)
    {}

    __device__
    void operator()()
    {
      // guard use of CUDA built-ins from foreign compilers
#ifdef __CUDA_ARCH__
      typedef int size_type;

      const size_type grid_size = gridDim.x * blockDim.x;

      for(size_type tid = blockDim.x * blockIdx.x + threadIdx.x;
          tid < super_t::g.size();
          tid += grid_size)
      {
        // instantiate a view of the exec group
        parallel_group<agent<grainsize>,groupsize> this_group(
          1,
          agent<grainsize>(tid),
          0
        );

        substitute_placeholders_and_execute(this_group, super_t::c);
      } // end for
#endif
    } // end operator()
}; // end cuda_task

} // end detail
} // end bulk
BULK_NAMESPACE_SUFFIX

<|endoftext|>


<commit_before><commit_msg>fdo#45879 - fix selected gluepoint rendering.<commit_after><|endoftext|>