<commit_before>#include <Halide.h>
using namespace Halide;

Var x("x"), y("y"), c("c");

HalideExtern_3(int, my_rand, int, int, int);

Expr rand_float(Expr x, Expr y, Expr c, Expr min, Expr max) {
    Expr r = cast<float>(my_rand(x, y, c)) / RAND_MAX;
    return lerp(min, max, r);
}

int main(int argc, char **argv) {

    bool can_vectorize = (get_target_from_environment().arch != Target::PNaCl);

    // First define the function that gives the initial state.
    {
        Func initial;

        // The initial state is a quantity of three chemicals present at each pixel
        initial(x, y, c) = rand_float(x, y, c, 0.0f, 1.0f);
        initial.compile_to_file("reaction_diffusion_2_init");
    }

    // Then the function that updates the state. Also depends on user input.
    {
        ImageParam state(Float(32), 3);
        Param<int> mouse_x, mouse_y;

        Func clamped;
        clamped(x, y, c) = state(clamp(x, 0, state.width()-1), clamp(y, 0, state.height()-1), c);

        RDom kernel(-1, 3);
        Func g, gaussian;
        g(x) = exp(-x*x*0.4f);
        gaussian(x) = g(x) / sum(g(kernel));
        gaussian.compute_root();

        Func blur_x, blur_y;
        blur_x(x, y, c) = sum(gaussian(kernel) * clamped(x + kernel, y, c));
        blur_y(x, y, c) = sum(gaussian(kernel) * blur_x(x, y + kernel, c));

        // Diffusion
        Expr R = blur_y(x, y, 0);
        Expr G = blur_y(x, y, 1);
        Expr B = blur_y(x, y, 2);

        // Push the colors outwards with a sigmoid
        //Expr s = 0.3f;
        //Expr s = lerp(1.0f, 3.0f, y / 1024.0f);
        Expr s = 2.0f;
        //Expr s = 0.5298f;
        R *= (1 - s) + s * R * (3 - 2 * R);
        G *= (1 - s) + s * G * (3 - 2 * G);
        B *= (1 - s) + s * B * (3 - 2 * B);

        // Reaction
        Expr mR = 1.0f - R;
        Expr mG = 1.0f - G;
        Expr mB = 1.0f - B;

        Expr dR = B * (mR * mG - R * G);
        Expr dG = mB * (R * mG - mR * G);
        Expr dB = (mR * (mG * mB - G * B) + R * (G * mB - mG * B));

        // Things brighten faster than they decay
        dR = select(dR > 0, dR * 2.25f, dR);
        dG = select(dG > 0, dG * 2.5f, dG);
        dB = select(dB < 0, dB * 2.5f, dB);

        Expr dx = (x - 512)/512.0f, dy = (y - 512)/512.0f;
        Expr radius = dx * dx + dy*dy;
        //Expr t = lerp(0.195f, 0.198f, x/1024.0f);
        //Expr t = (2.0f - radius) * 0.05f;
        //Expr t = 0.0651f;
        Expr t = 0.196f;

        R += t * dR;
        G += t * dG;
        B += t * dB;

        R = clamp(R, 0.0f, 1.0f);
        G = clamp(G, 0.0f, 1.0f);
        B = clamp(B, 0.0f, 1.0f);

        Func new_state;
        new_state(x, y, c) = select(c == 0, R, select(c == 1, G, B));

        // Add some white where the mouse is
        Expr min_x = clamp(mouse_x - 10, 0, state.width()-1);
        Expr max_x = clamp(mouse_x + 10, 0, state.width()-1);
        Expr min_y = clamp(mouse_y - 10, 0, state.height()-1);
        Expr max_y = clamp(mouse_y + 10, 0, state.height()-1);
        RDom clobber(min_x, max_x - min_x + 1, min_y, max_y - min_y + 1);

        dx = clobber.x - mouse_x;
        dy = clobber.y - mouse_y;
        radius = dx * dx + dy * dy;
        new_state(clobber.x, clobber.y, c) = select(radius < 100.0f, 1.0f, new_state(clobber.x, clobber.y, c));

        new_state.reorder(c, x, y).bound(c, 0, 3).unroll(c);

        Var yi;
        new_state.split(y, y, yi, 16).parallel(y);

        blur_x.store_at(new_state, y).compute_at(new_state, yi);
        blur_y.store_at(new_state, y).compute_at(new_state, yi);
        clamped.store_at(new_state, y).compute_at(new_state, yi);

        if (can_vectorize) {
            new_state.vectorize(x, 4);
            blur_x.vectorize(x, 4);
            blur_y.vectorize(x, 4);
        }

        new_state.compile_to_file("reaction_diffusion_2_update", state, mouse_x, mouse_y);
    }

    // Now the function that converts the state into an argb image.
    {
        ImageParam state(Float(32), 3);

        Expr R = state(x, y, 0), G = state(x, y, 1), B = state(x, y, 2);

        Expr alpha = 255 << 24;
        Expr red = cast<int32_t>(R * 255) * (1 << 16);
        Expr green = cast<int32_t>(G * 255) * (1 << 8);
        Expr blue = cast<int32_t>(B * 255);

        Func render;
        render(x, y) = alpha + red + green + blue;

        if (can_vectorize) {
            render.vectorize(x, 4);
        }
        Var yi;
        render.split(y, y, yi, 16).parallel(y);

        render.compile_to_file("reaction_diffusion_2_render", state);
    }

    return 0;
}
<commit_msg>Simplified the math in reaction diffusion demo.<commit_after>#include <Halide.h>
using namespace Halide;

Var x("x"), y("y"), c("c");

HalideExtern_3(int, my_rand, int, int, int);

Expr rand_float(Expr x, Expr y, Expr c, Expr min, Expr max) {
    Expr r = cast<float>(my_rand(x, y, c)) / RAND_MAX;
    return lerp(min, max, r);
}

int main(int argc, char **argv) {

    bool can_vectorize = (get_target_from_environment().arch != Target::PNaCl);

    // First define the function that gives the initial state.
    {
        Func initial;

        // The initial state is a quantity of three chemicals present at each pixel
        initial(x, y, c) = rand_float(x, y, c, 0.0f, 1.0f);
        initial.compile_to_file("reaction_diffusion_2_init");
    }

    // Then the function that updates the state. Also depends on user input.
    {
        ImageParam state(Float(32), 3);
        Param<int> mouse_x, mouse_y;

        Func clamped;
        clamped(x, y, c) = state(clamp(x, 0, state.width()-1), clamp(y, 0, state.height()-1), c);

        RDom kernel(-1, 3);
        Func g, gaussian;
        g(x) = exp(-x*x*0.4f);
        gaussian(x) = g(x) / sum(g(kernel));
        gaussian.compute_root();

        Func blur_x, blur_y;
        blur_x(x, y, c) = sum(gaussian(kernel) * clamped(x + kernel, y, c));
        blur_y(x, y, c) = sum(gaussian(kernel) * blur_x(x, y + kernel, c));

        // Diffusion
        Expr R = blur_y(x, y, 0);
        Expr G = blur_y(x, y, 1);
        Expr B = blur_y(x, y, 2);

        // Push the colors outwards with a sigmoid
        //Expr s = 0.3f;
        //Expr s = lerp(1.0f, 3.0f, y / 1024.0f);
        Expr s = 2.0f;
        //Expr s = 0.5298f;
        R *= (1 - s) + s * R * (3 - 2 * R);
        G *= (1 - s) + s * G * (3 - 2 * G);
        B *= (1 - s) + s * B * (3 - 2 * B);

        // Reaction
        Expr dR = B * (1 - R - G);
        Expr dG = (1 - B) * (R - G);
        Expr dB = 1 - B + 2 * G * R - R - G;

        // Red and green increase faster than they decay
        dR = select(dR > 0, dR * 2.25f, dR);
        dG = select(dG > 0, dG * 2.5f, dG);

        // Blue decays faster that it increases
        dB = select(dB < 0, dB * 2.5f, dB);

        Expr dx = (x - 512)/512.0f, dy = (y - 512)/512.0f;
        Expr radius = dx * dx + dy*dy;
        //Expr t = lerp(0.195f, 0.198f, x/1024.0f);
        //Expr t = (2.0f - radius) * 0.05f;
        //Expr t = 0.0651f;
        Expr t = 0.196f;

        R += t * dR;
        G += t * dG;
        B += t * dB;

        R = clamp(R, 0.0f, 1.0f);
        G = clamp(G, 0.0f, 1.0f);
        B = clamp(B, 0.0f, 1.0f);

        Func new_state;
        new_state(x, y, c) = select(c == 0, R, select(c == 1, G, B));

        // Add some white where the mouse is
        Expr min_x = clamp(mouse_x - 10, 0, state.width()-1);
        Expr max_x = clamp(mouse_x + 10, 0, state.width()-1);
        Expr min_y = clamp(mouse_y - 10, 0, state.height()-1);
        Expr max_y = clamp(mouse_y + 10, 0, state.height()-1);
        RDom clobber(min_x, max_x - min_x + 1, min_y, max_y - min_y + 1);

        dx = clobber.x - mouse_x;
        dy = clobber.y - mouse_y;
        radius = dx * dx + dy * dy;
        new_state(clobber.x, clobber.y, c) = select(radius < 100.0f, 1.0f, new_state(clobber.x, clobber.y, c));

        new_state.reorder(c, x, y).bound(c, 0, 3).unroll(c);

        Var yi;
        new_state.split(y, y, yi, 16).parallel(y);

        blur_x.store_at(new_state, y).compute_at(new_state, yi);
        blur_y.store_at(new_state, y).compute_at(new_state, yi);
        clamped.store_at(new_state, y).compute_at(new_state, yi);

        if (can_vectorize) {
            new_state.vectorize(x, 4);
            blur_x.vectorize(x, 4);
            blur_y.vectorize(x, 4);
        }

        new_state.compile_to_file("reaction_diffusion_2_update", state, mouse_x, mouse_y);
    }

    // Now the function that converts the state into an argb image.
    {
        ImageParam state(Float(32), 3);

        Expr R = state(x, y, 0), G = state(x, y, 1), B = state(x, y, 2);

        Expr alpha = 255 << 24;
        Expr red = cast<int32_t>(R * 255) * (1 << 16);
        Expr green = cast<int32_t>(G * 255) * (1 << 8);
        Expr blue = cast<int32_t>(B * 255);

        Func render;
        render(x, y) = alpha + red + green + blue;

        if (can_vectorize) {
            render.vectorize(x, 4);
        }
        Var yi;
        render.split(y, y, yi, 16).parallel(y);

        render.compile_to_file("reaction_diffusion_2_render", state);
    }

    return 0;
}
<|endoftext|>


<commit_before>/**
 * \file
 * Copyright 2016 Benjamin Worpitz
 *
 * This file is part of alpaka.
 *
 * alpaka is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * alpaka is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with alpaka.
 * If not, see <http://www.gnu.org/licenses/>.
 */

// \Hack: Boost.MPL defines BOOST_MPL_CFG_GPU_ENABLED to __host__ __device__ if nvcc is used.
// BOOST_AUTO_TEST_CASE_TEMPLATE and its internals are not GPU enabled but is using boost::mpl::for_each internally.
// For each template parameter this leads to:
// /home/travis/build/boost/boost/mpl/for_each.hpp(78): warning: calling a __host__ function from a __host__ __device__ function is not allowed
// because boost::mpl::for_each has the BOOST_MPL_CFG_GPU_ENABLED attribute but the test internals are pure host methods.
// Because we do not use MPL within GPU code here, we can disable the MPL GPU support.
#define BOOST_MPL_CFG_GPU_ENABLED

#include <alpaka/alpaka.hpp>
#include <alpaka/test/acc/Acc.hpp>                  // alpaka::test::acc::TestAccs
#include <alpaka/test/KernelExecutionFixture.hpp>   // alpaka::test::KernelExecutionFixture

#include <boost/assert.hpp>                         // BOOST_VERIFY
#include <boost/predef.h>                           // BOOST_COMP_CLANG
#if BOOST_COMP_CLANG
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wunused-parameter"
#endif
#include <boost/test/unit_test.hpp>
#if BOOST_COMP_CLANG
    #pragma clang diagnostic pop
#endif

//#############################################################################
//!
//#############################################################################
class AtomicTestKernel
{
public:
    //-----------------------------------------------------------------------------
    //!
    //-----------------------------------------------------------------------------
    ALPAKA_NO_HOST_ACC_WARNING
    template<
        typename TAcc,
        typename T>
    ALPAKA_FN_ACC auto operator()(
        TAcc const & acc,
        T operandOrig) const
    -> void
    {
        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Add
        {
            T operand = operandOrig;
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Add>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = operandOrig + value;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Sub
        {
            T operand = operandOrig;
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Sub>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = operandOrig - value;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Min
        {
            T operand = operandOrig;
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Min>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = std::min(operandOrig, value);
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Max
        {
            T operand = operandOrig;
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Max>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = std::max(operandOrig, value);
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Exch
        {
            T operand = operandOrig;
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Exch>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = value;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Inc
        {
            // \TODO: Check reset to 0 at 'value'.
            T operand = operandOrig;
            T const value = static_cast<T>(42);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Inc>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = operandOrig + 1;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Dec
        {
            // \TODO: Check reset to 'value' at 0.
            T operand = operandOrig;
            T const value = static_cast<T>(42);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Dec>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = operandOrig - 1;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::And
        {
            T operand = operandOrig;
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::And>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = operandOrig & value;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Or
        {
            T operand = operandOrig;
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Or>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = operandOrig | value;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Xor
        {
            T operand = operandOrig;
            T const value = operandOrig + static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Xor>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = operandOrig ^ value;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Cas with match
        {
            T operand = operandOrig;
            T const compare = operandOrig;
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Cas>(
                        acc,
                        &operand,
                        compare,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = value;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Cas without match
        {
            T operand = operandOrig;
            T const compare = operandOrig + static_cast<T>(1);
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Cas>(
                        acc,
                        &operand,
                        compare,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = operandOrig;
            BOOST_VERIFY(operand == reference);
        }
    }
};

BOOST_AUTO_TEST_SUITE(atomic)

//#############################################################################
//!
//#############################################################################
template<
    typename TAcc,
    typename T,
    typename TSfinae = void>
struct TestAtomicOperations
{
    //-----------------------------------------------------------------------------
    //
    //-----------------------------------------------------------------------------
    static auto testAtomicOperations()
    -> void
    {
        using Dim = alpaka::dim::Dim<TAcc>;
        using Size = alpaka::size::Size<TAcc>;

        alpaka::test::KernelExecutionFixture<TAcc> fixture(
            alpaka::vec::Vec<Dim, Size>::ones());

        AtomicTestKernel kernel;

        T value = static_cast<T>(32);
        BOOST_REQUIRE_EQUAL(
            true,
            fixture(
                kernel,
                value));
    }
};

#if defined(ALPAKA_ACC_GPU_CUDA_ENABLED) && BOOST_LANG_CUDA
//#############################################################################
// NOTE: std::uint32_t is the only type supported by all atomic CUDA operations.
//#############################################################################
template<
    typename TDim,
    typename TSize,
    typename T>
struct TestAtomicOperations<
    alpaka::acc::AccGpuCudaRt<TDim, TSize>,
    T,
    typename std::enable_if<!std::is_same<std::uint32_t, T>::value>::type>
{
    //-----------------------------------------------------------------------------
    //
    //-----------------------------------------------------------------------------
    static auto testAtomicOperations()
    -> void
    {
        // All other types are not supported by all CUDA atomic operations.
    }
};
#endif

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE_TEMPLATE(
    atomicOperationsWorking,
    TAcc,
    alpaka::test::acc::TestAccs)
{
    // This test exceeds the maximum compilation time.
#if !ALPAKA_CI
    TestAtomicOperations<TAcc, std::int8_t>::testAtomicOperations();
    TestAtomicOperations<TAcc, std::uint8_t>::testAtomicOperations();
    TestAtomicOperations<TAcc, std::int16_t>::testAtomicOperations();
    TestAtomicOperations<TAcc, std::uint16_t>::testAtomicOperations();
#endif
    TestAtomicOperations<TAcc, std::int32_t>::testAtomicOperations();
#if !ALPAKA_CI
    TestAtomicOperations<TAcc, std::uint32_t>::testAtomicOperations();
    TestAtomicOperations<TAcc, std::int64_t>::testAtomicOperations();
    TestAtomicOperations<TAcc, std::uint64_t>::testAtomicOperations();
#endif
    // Not all atomic operations are possible with floating point values.
    //TestAtomicOperations<TAcc, float>::testAtomicOperations();
    //TestAtomicOperations<TAcc, double>::testAtomicOperations();
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>replace std::min and std::max in kernel with ternary operators<commit_after>/**
 * \file
 * Copyright 2016 Benjamin Worpitz
 *
 * This file is part of alpaka.
 *
 * alpaka is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * alpaka is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with alpaka.
 * If not, see <http://www.gnu.org/licenses/>.
 */

// \Hack: Boost.MPL defines BOOST_MPL_CFG_GPU_ENABLED to __host__ __device__ if nvcc is used.
// BOOST_AUTO_TEST_CASE_TEMPLATE and its internals are not GPU enabled but is using boost::mpl::for_each internally.
// For each template parameter this leads to:
// /home/travis/build/boost/boost/mpl/for_each.hpp(78): warning: calling a __host__ function from a __host__ __device__ function is not allowed
// because boost::mpl::for_each has the BOOST_MPL_CFG_GPU_ENABLED attribute but the test internals are pure host methods.
// Because we do not use MPL within GPU code here, we can disable the MPL GPU support.
#define BOOST_MPL_CFG_GPU_ENABLED

#include <alpaka/alpaka.hpp>
#include <alpaka/test/acc/Acc.hpp>                  // alpaka::test::acc::TestAccs
#include <alpaka/test/KernelExecutionFixture.hpp>   // alpaka::test::KernelExecutionFixture

#include <boost/assert.hpp>                         // BOOST_VERIFY
#include <boost/predef.h>                           // BOOST_COMP_CLANG
#if BOOST_COMP_CLANG
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wunused-parameter"
#endif
#include <boost/test/unit_test.hpp>
#if BOOST_COMP_CLANG
    #pragma clang diagnostic pop
#endif

//#############################################################################
//!
//#############################################################################
class AtomicTestKernel
{
public:
    //-----------------------------------------------------------------------------
    //!
    //-----------------------------------------------------------------------------
    ALPAKA_NO_HOST_ACC_WARNING
    template<
        typename TAcc,
        typename T>
    ALPAKA_FN_ACC auto operator()(
        TAcc const & acc,
        T operandOrig) const
    -> void
    {
        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Add
        {
            T operand = operandOrig;
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Add>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = operandOrig + value;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Sub
        {
            T operand = operandOrig;
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Sub>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = operandOrig - value;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Min
        {
            T operand = operandOrig;
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Min>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = (operandOrig < value) ? operandOrig : value;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Max
        {
            T operand = operandOrig;
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Max>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = (operandOrig > value) ? operandOrig : value;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Exch
        {
            T operand = operandOrig;
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Exch>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = value;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Inc
        {
            // \TODO: Check reset to 0 at 'value'.
            T operand = operandOrig;
            T const value = static_cast<T>(42);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Inc>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = operandOrig + 1;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Dec
        {
            // \TODO: Check reset to 'value' at 0.
            T operand = operandOrig;
            T const value = static_cast<T>(42);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Dec>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = operandOrig - 1;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::And
        {
            T operand = operandOrig;
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::And>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = operandOrig & value;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Or
        {
            T operand = operandOrig;
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Or>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = operandOrig | value;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Xor
        {
            T operand = operandOrig;
            T const value = operandOrig + static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Xor>(
                        acc,
                        &operand,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = operandOrig ^ value;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Cas with match
        {
            T operand = operandOrig;
            T const compare = operandOrig;
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Cas>(
                        acc,
                        &operand,
                        compare,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = value;
            BOOST_VERIFY(operand == reference);
        }

        //-----------------------------------------------------------------------------
        // alpaka::atomic::op::Cas without match
        {
            T operand = operandOrig;
            T const compare = operandOrig + static_cast<T>(1);
            T const value = static_cast<T>(4);
            T const ret =
                alpaka::atomic::atomicOp<
                    alpaka::atomic::op::Cas>(
                        acc,
                        &operand,
                        compare,
                        value);
            BOOST_VERIFY(operandOrig == ret);
            T const reference = operandOrig;
            BOOST_VERIFY(operand == reference);
        }
    }
};

BOOST_AUTO_TEST_SUITE(atomic)

//#############################################################################
//!
//#############################################################################
template<
    typename TAcc,
    typename T,
    typename TSfinae = void>
struct TestAtomicOperations
{
    //-----------------------------------------------------------------------------
    //
    //-----------------------------------------------------------------------------
    static auto testAtomicOperations()
    -> void
    {
        using Dim = alpaka::dim::Dim<TAcc>;
        using Size = alpaka::size::Size<TAcc>;

        alpaka::test::KernelExecutionFixture<TAcc> fixture(
            alpaka::vec::Vec<Dim, Size>::ones());

        AtomicTestKernel kernel;

        T value = static_cast<T>(32);
        BOOST_REQUIRE_EQUAL(
            true,
            fixture(
                kernel,
                value));
    }
};

#if defined(ALPAKA_ACC_GPU_CUDA_ENABLED) && BOOST_LANG_CUDA
//#############################################################################
// NOTE: std::uint32_t is the only type supported by all atomic CUDA operations.
//#############################################################################
template<
    typename TDim,
    typename TSize,
    typename T>
struct TestAtomicOperations<
    alpaka::acc::AccGpuCudaRt<TDim, TSize>,
    T,
    typename std::enable_if<!std::is_same<std::uint32_t, T>::value>::type>
{
    //-----------------------------------------------------------------------------
    //
    //-----------------------------------------------------------------------------
    static auto testAtomicOperations()
    -> void
    {
        // All other types are not supported by all CUDA atomic operations.
    }
};
#endif

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE_TEMPLATE(
    atomicOperationsWorking,
    TAcc,
    alpaka::test::acc::TestAccs)
{
    // This test exceeds the maximum compilation time.
#if !ALPAKA_CI
    TestAtomicOperations<TAcc, std::int8_t>::testAtomicOperations();
    TestAtomicOperations<TAcc, std::uint8_t>::testAtomicOperations();
    TestAtomicOperations<TAcc, std::int16_t>::testAtomicOperations();
    TestAtomicOperations<TAcc, std::uint16_t>::testAtomicOperations();
#endif
    TestAtomicOperations<TAcc, std::int32_t>::testAtomicOperations();
#if !ALPAKA_CI
    TestAtomicOperations<TAcc, std::uint32_t>::testAtomicOperations();
    TestAtomicOperations<TAcc, std::int64_t>::testAtomicOperations();
    TestAtomicOperations<TAcc, std::uint64_t>::testAtomicOperations();
#endif
    // Not all atomic operations are possible with floating point values.
    //TestAtomicOperations<TAcc, float>::testAtomicOperations();
    //TestAtomicOperations<TAcc, double>::testAtomicOperations();
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>// ws2812_lib.cpp
//
// main library file / contains class implementation
//
// Need to give credits to  Charles Lohr (https://github.com/cnlohr due
// to his work on his software for driving ws2812 led-strips using
// the i2s interface of the ESP8266.
//
// This inspired me to create an ESP8266 library for the Arduino IDE
// I've added temporal dithering & gamma-correction
// for a 'more natural' light intensity profile.
//
// No pin-definitions/mapings are required/possible as the library used the I2S
// output-pin. This pin in it's turn is shared with GPIO3 & RXD0
//

#include <Arduino.h>
#include <stdint.h>
#include "ws2812_i2s.h"
#include "ws2812_defs.h"
#include "ws2812_gamma.h"

// include C-style header
extern "C"
{
#include "ws2812_dma.h"
};

// class constructor
WS2812::WS2812(void)
{
  // empty for now
}

// class de-constructor
WS2812::~WS2812(void)
{
  // empty for now
  // TODO : should implement switching of DMA
}

// Init led-string / memory buffers etc.
void WS2812::init(uint16_t _num_leds)
{
  uint8_t i;
  uint16_t j;

  num_leds = _num_leds;

  // clear zero buffer
  for(j=0; j<NUM_I2S_ZERO_WORDS; j++)
  {
    i2s_zeros_buffer[j] = 0;
  }

  // do memory allocation for i2s buffer(s)
  for(i=0; i<WS2812_DITHER_NUM; i++)
  {
    i2s_pixels_buffer[i] = new uint32_t[NUM_I2S_PIXEL_WORDS];

    // TODO : handle memory allocation error better
    if (i2s_pixels_buffer[i] == 0)
    {
      Serial.println("WS2812_I2S : ERROR ALLOCATING MEMORY");
      return;
    }

    for(j=0; j<NUM_I2S_PIXEL_WORDS; j++)
    {
      i2s_pixels_buffer[i][j] = 0;
    }
  }

  // set-up DMA descriptors / 1 pair per dither-factor
  for(i=0; i<WS2812_DITHER_NUM; i++)
  {
    i2s_pixels_queue[i].owner     = 1;
    i2s_pixels_queue[i].eof       = 1;
    i2s_pixels_queue[i].sub_sof   = 0;
    i2s_pixels_queue[i].datalen   = NUM_I2S_PIXEL_BYTES;     // Size in bytes
    i2s_pixels_queue[i].blocksize = NUM_I2S_PIXEL_BYTES;     // Size in bytes
    i2s_pixels_queue[i].buf_ptr   = (uint32_t)i2s_pixels_buffer[i];
    i2s_pixels_queue[i].unused    = 0;
    i2s_pixels_queue[i].next_link_ptr = (uint32_t)&i2s_zeros_queue[i];  // always link to zeros-buffer

    i2s_zeros_queue[i].owner      = 1;
    i2s_zeros_queue[i].eof        = 1;
    i2s_zeros_queue[i].sub_sof    = 0;
    i2s_zeros_queue[i].datalen    = NUM_I2S_ZERO_BYTES;      // Size in bytes)
    i2s_zeros_queue[i].blocksize  = NUM_I2S_ZERO_BYTES;      // Size in bytes
    i2s_zeros_queue[i].buf_ptr    = (uint32_t)i2s_zeros_buffer;
    i2s_zeros_queue[i].unused     = 0;

    if (i == (WS2812_DITHER_NUM-1)) // last DMA descriptor in linked list ?
    {
      // yes : link to first DMA descriptor
      i2s_zeros_queue[i].next_link_ptr = (uint32_t)&i2s_pixels_queue[0];
    }
    else
    {
      // no : link to next DMA descriptor
      i2s_zeros_queue[i].next_link_ptr = (uint32_t)&i2s_pixels_queue[i+1];
    }
  }

  // call C based helper function
  // I did not really succeed in putting the code from the helper
  // funtion directly into this constructor...has something to do
  // with  C vs. C++
  // the i2c_writeReg_Mask macro (+ others) failed.. see ws2812_defs.h
  // may be I solve this later

  // parameter = first entry in DMA descriptor list, i.e the descriptor list
  ws2812_dma(i2s_pixels_queue);

}

// left this comment in tact....credit to Charles

// All functions below this line are Public Domain 2015 Charles Lohr.
// this code may be used by anyone in any way without restriction or limitation.

// Send out WS2812 bits with coded pulses, one nibble, then the other.
static const uint16_t bitpatterns[16] =
{
  0b1000100010001000, 0b1000100010001110, 0b1000100011101000, 0b1000100011101110,
  0b1000111010001000, 0b1000111010001110, 0b1000111011101000, 0b1000111011101110,
  0b1110100010001000, 0b1110100010001110, 0b1110100011101000, 0b1110100011101110,
  0b1110111010001000, 0b1110111010001110, 0b1110111011101000, 0b1110111011101110,
};

// display the pixels
void WS2812::show(Pixel_t *pixels)
{
  uint8_t *buffer;
  uint8_t pixelbyte;
  uint8_t gammabyte;
  uint16_t i,b;
  uint16_t *i2s_ptr[WS2812_DITHER_NUM];

  buffer = (uint8_t *)pixels;

  // set-up pointers into the i2s-pixel-buffers
  for(i=0; i<WS2812_DITHER_NUM; i++)
  {
    i2s_ptr[i] = (uint16_t *)i2s_pixels_buffer[i];
  }

  // for every pixel in the input-array
  // - get the pixel value (either R,G, or B)
  // - for every dithered buffer
  //   get the gamma-corrected output value
  // - and transform into i2s nibble

  for(b=0; b<NUM_RGB_BYTES; b++)
  {
    pixelbyte = *buffer++;

    for(i=0; i<WS2812_DITHER_NUM; i++)
    {
      gammabyte = gamma_dither[i][pixelbyte];
      *(i2s_ptr[i]++) = bitpatterns[ (gammabyte & 0x0f) ];
      *(i2s_ptr[i]++) = bitpatterns[ (gammabyte>>4) & 0x0f ];
    }
  }

}

// end of file
<commit_msg>Delete ws2812_i2s.cpp<commit_after><|endoftext|>


<commit_before>//===-- MipsDelaySlotFiller.cpp - Mips Delay Slot Filler ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Simple pass to fill delay slots with useful instructions.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "delay-slot-filler"

#include "Mips.h"
#include "MipsTargetMachine.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"

using namespace llvm;

STATISTIC(FilledSlots, "Number of delay slots filled");
STATISTIC(UsefulSlots, "Number of delay slots filled with instructions that"
                       " are not NOP.");

static cl::opt<bool> DisableDelaySlotFiller(
  "disable-mips-delay-filler",
  cl::init(false),
  cl::desc("Fill all delay slots with NOPs."),
  cl::Hidden);

// This option can be used to silence complaints by machine verifier passes.
static cl::opt<bool> SkipDelaySlotFiller(
  "skip-mips-delay-filler",
  cl::init(false),
  cl::desc("Skip MIPS' delay slot filling pass."),
  cl::Hidden);

namespace {
  class Filler : public MachineFunctionPass {
  public:
    Filler(TargetMachine &tm)
      : MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()) { }

    virtual const char *getPassName() const {
      return "Mips Delay Slot Filler";
    }

    bool runOnMachineFunction(MachineFunction &F) {
      if (SkipDelaySlotFiller)
        return false;

      bool Changed = false;
      for (MachineFunction::iterator FI = F.begin(), FE = F.end();
           FI != FE; ++FI)
        Changed |= runOnMachineBasicBlock(*FI);
      return Changed;
    }

  private:
    typedef MachineBasicBlock::iterator Iter;
    typedef MachineBasicBlock::reverse_iterator ReverseIter;

    bool runOnMachineBasicBlock(MachineBasicBlock &MBB);

    void insertDefsUses(const MachineInstr &MI, SmallSet<unsigned, 32> &RegDefs,
                        SmallSet<unsigned, 32> &RegUses) const;

    bool isRegInSet(const SmallSet<unsigned, 32> &RegSet, unsigned Reg) const;

    bool delayHasHazard(const MachineInstr &Candidate, bool &SawLoad,
                        bool &SawStore, const SmallSet<unsigned, 32> &RegDefs,
                        const SmallSet<unsigned, 32> &RegUses) const;

    bool findDelayInstr(MachineBasicBlock &MBB, Iter slot, Iter &Filler) const;

    bool terminateSearch(const MachineInstr &Candidate) const;

    TargetMachine &TM;
    const TargetInstrInfo *TII;

    static char ID;
  };
  char Filler::ID = 0;
} // end of anonymous namespace

/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
/// We assume there is only one delay slot per delayed instruction.
bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
  bool Changed = false;

  for (Iter I = MBB.begin(); I != MBB.end(); ++I) {
    if (!I->hasDelaySlot())
      continue;

    ++FilledSlots;
    Changed = true;
    Iter D;

    // Delay slot filling is disabled at -O0.
    if (!DisableDelaySlotFiller && (TM.getOptLevel() != CodeGenOpt::None) &&
        findDelayInstr(MBB, I, D)) {
      MBB.splice(llvm::next(I), &MBB, D);
      ++UsefulSlots;
    } else
      BuildMI(MBB, llvm::next(I), I->getDebugLoc(), TII->get(Mips::NOP));

    // Bundle the delay slot filler to the instruction with the delay slot.
    MIBundleBuilder(MBB, I, llvm::next(llvm::next(I)));
  }

  return Changed;
}

/// createMipsDelaySlotFillerPass - Returns a pass that fills in delay
/// slots in Mips MachineFunctions
FunctionPass *llvm::createMipsDelaySlotFillerPass(MipsTargetMachine &tm) {
  return new Filler(tm);
}

bool Filler::findDelayInstr(MachineBasicBlock &MBB, Iter Slot,
                            Iter &Filler) const {
  SmallSet<unsigned, 32> RegDefs;
  SmallSet<unsigned, 32> RegUses;

  insertDefsUses(*Slot, RegDefs, RegUses);

  bool SawLoad = false;
  bool SawStore = false;

  for (ReverseIter I(Slot); I != MBB.rend(); ++I) {
    // skip debug value
    if (I->isDebugValue())
      continue;

    if (terminateSearch(*I))
      break;

    if (delayHasHazard(*I, SawLoad, SawStore, RegDefs, RegUses)) {
      insertDefsUses(*I, RegDefs, RegUses);
      continue;
    }

    Filler = llvm::next(I).base();
    return true;
  }

  return false;
}

bool Filler::delayHasHazard(const MachineInstr &Candidate, bool &SawLoad,
                            bool &SawStore,
                            const SmallSet<unsigned, 32> &RegDefs,
                            const SmallSet<unsigned, 32> &RegUses) const {
  if (Candidate.isImplicitDef() || Candidate.isKill())
    return true;

  // Loads or stores cannot be moved past a store to the delay slot
  // and stores cannot be moved past a load.
  if (Candidate.mayLoad()) {
    if (SawStore)
      return true;
    SawLoad = true;
  }

  if (Candidate.mayStore()) {
    if (SawStore)
      return true;
    SawStore = true;
    if (SawLoad)
      return true;
  }

  assert((!Candidate.isCall() && !Candidate.isReturn()) &&
         "Cannot put calls or returns in delay slot.");

  for (unsigned I = 0, E = Candidate.getNumOperands(); I != E; ++I) {
    const MachineOperand &MO = Candidate.getOperand(I);
    unsigned Reg;

    if (!MO.isReg() || !(Reg = MO.getReg()))
      continue; // skip

    if (MO.isDef()) {
      // check whether Reg is defined or used before delay slot.
      if (isRegInSet(RegDefs, Reg) || isRegInSet(RegUses, Reg))
        return true;
    }
    if (MO.isUse()) {
      // check whether Reg is defined before delay slot.
      if (isRegInSet(RegDefs, Reg))
        return true;
    }
  }
  return false;
}

// Helper function for getting a MachineOperand's register number and adding it
// to RegDefs or RegUses.
static void insertDefUse(const MachineOperand &MO,
                         SmallSet<unsigned, 32> &RegDefs,
                         SmallSet<unsigned, 32> &RegUses,
                         unsigned ExcludedReg = 0) {
  unsigned Reg;

  if (!MO.isReg() || !(Reg = MO.getReg()) || (Reg == ExcludedReg))
    return;

  if (MO.isDef())
    RegDefs.insert(Reg);
  else if (MO.isUse())
    RegUses.insert(Reg);
}

// Insert Defs and Uses of MI into the sets RegDefs and RegUses.
void Filler::insertDefsUses(const MachineInstr &MI,
                            SmallSet<unsigned, 32> &RegDefs,
                            SmallSet<unsigned, 32> &RegUses) const {
  unsigned I, E = MI.getDesc().getNumOperands();

  for (I = 0; I != E; ++I)
    insertDefUse(MI.getOperand(I), RegDefs, RegUses);

  // If MI is a call, add RA to RegDefs to prevent users of RA from going into
  // delay slot.
  if (MI.isCall()) {
    RegDefs.insert(Mips::RA);
    return;
  }

  // Return if MI is a return.
  if (MI.isReturn())
    return;

  // Examine the implicit operands. Exclude register AT which is in the list of
  // clobbered registers of branch instructions.
  E = MI.getNumOperands();
  for (; I != E; ++I)
    insertDefUse(MI.getOperand(I), RegDefs, RegUses, Mips::AT);
}

//returns true if the Reg or its alias is in the RegSet.
bool Filler::isRegInSet(const SmallSet<unsigned, 32> &RegSet,
                        unsigned Reg) const {
  // Check Reg and all aliased Registers.
  for (MCRegAliasIterator AI(Reg, TM.getRegisterInfo(), true);
       AI.isValid(); ++AI)
    if (RegSet.count(*AI))
      return true;
  return false;
}

bool Filler::terminateSearch(const MachineInstr &Candidate) const {
  return (Candidate.isTerminator() || Candidate.isCall() ||
          Candidate.isLabel() || Candidate.isInlineAsm() ||
          Candidate.hasUnmodeledSideEffects());
}
<commit_msg>[mips] Replace usage of SmallSet with BitVector, which is used to keep track of defined and used registers. Also add a few helper functions to simplify the code. <commit_after>//===-- MipsDelaySlotFiller.cpp - Mips Delay Slot Filler ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Simple pass to fill delay slots with useful instructions.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "delay-slot-filler"

#include "Mips.h"
#include "MipsTargetMachine.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"

using namespace llvm;

STATISTIC(FilledSlots, "Number of delay slots filled");
STATISTIC(UsefulSlots, "Number of delay slots filled with instructions that"
                       " are not NOP.");

static cl::opt<bool> DisableDelaySlotFiller(
  "disable-mips-delay-filler",
  cl::init(false),
  cl::desc("Fill all delay slots with NOPs."),
  cl::Hidden);

// This option can be used to silence complaints by machine verifier passes.
static cl::opt<bool> SkipDelaySlotFiller(
  "skip-mips-delay-filler",
  cl::init(false),
  cl::desc("Skip MIPS' delay slot filling pass."),
  cl::Hidden);

namespace {
  class Filler : public MachineFunctionPass {
  public:
    Filler(TargetMachine &tm)
      : MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()) { }

    virtual const char *getPassName() const {
      return "Mips Delay Slot Filler";
    }

    bool runOnMachineFunction(MachineFunction &F) {
      if (SkipDelaySlotFiller)
        return false;

      bool Changed = false;
      for (MachineFunction::iterator FI = F.begin(), FE = F.end();
           FI != FE; ++FI)
        Changed |= runOnMachineBasicBlock(*FI);
      return Changed;
    }

  private:
    typedef MachineBasicBlock::iterator Iter;
    typedef MachineBasicBlock::reverse_iterator ReverseIter;

    bool runOnMachineBasicBlock(MachineBasicBlock &MBB);

    /// Initialize RegDefs and RegUses.
    void initRegDefsUses(const MachineInstr &MI, BitVector &RegDefs,
                         BitVector &RegUses) const;

    bool isRegInSet(const BitVector &RegSet, unsigned Reg) const;

    bool checkRegDefsUses(const BitVector &RegDefs, const BitVector &RegUses,
                          BitVector &NewDefs, BitVector &NewUses,
                          unsigned Reg, bool IsDef) const;

    bool checkRegDefsUses(BitVector &RegDefs, BitVector &RegUses,
                          const MachineInstr &MI, unsigned Begin,
                          unsigned End) const;

    /// This function checks if it is valid to move Candidate to the delay slot
    /// and returns true if it isn't. It also updates load and store flags and
    /// register defs and uses.
    bool delayHasHazard(const MachineInstr &Candidate, bool &SawLoad,
                        bool &SawStore, BitVector &RegDefs,
                        BitVector &RegUses) const;

    bool findDelayInstr(MachineBasicBlock &MBB, Iter slot, Iter &Filler) const;

    bool terminateSearch(const MachineInstr &Candidate) const;

    TargetMachine &TM;
    const TargetInstrInfo *TII;

    static char ID;
  };
  char Filler::ID = 0;
} // end of anonymous namespace

/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
/// We assume there is only one delay slot per delayed instruction.
bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
  bool Changed = false;

  for (Iter I = MBB.begin(); I != MBB.end(); ++I) {
    if (!I->hasDelaySlot())
      continue;

    ++FilledSlots;
    Changed = true;
    Iter D;

    // Delay slot filling is disabled at -O0.
    if (!DisableDelaySlotFiller && (TM.getOptLevel() != CodeGenOpt::None) &&
        findDelayInstr(MBB, I, D)) {
      MBB.splice(llvm::next(I), &MBB, D);
      ++UsefulSlots;
    } else
      BuildMI(MBB, llvm::next(I), I->getDebugLoc(), TII->get(Mips::NOP));

    // Bundle the delay slot filler to the instruction with the delay slot.
    MIBundleBuilder(MBB, I, llvm::next(llvm::next(I)));
  }

  return Changed;
}

/// createMipsDelaySlotFillerPass - Returns a pass that fills in delay
/// slots in Mips MachineFunctions
FunctionPass *llvm::createMipsDelaySlotFillerPass(MipsTargetMachine &tm) {
  return new Filler(tm);
}

bool Filler::findDelayInstr(MachineBasicBlock &MBB, Iter Slot,
                            Iter &Filler) const {
  unsigned NumRegs = TM.getRegisterInfo()->getNumRegs();
  BitVector RegDefs(NumRegs), RegUses(NumRegs);

  initRegDefsUses(*Slot, RegDefs, RegUses);

  bool SawLoad = false;
  bool SawStore = false;

  for (ReverseIter I(Slot); I != MBB.rend(); ++I) {
    // skip debug value
    if (I->isDebugValue())
      continue;

    if (terminateSearch(*I))
      break;

    if (delayHasHazard(*I, SawLoad, SawStore, RegDefs, RegUses))
      continue;

    Filler = llvm::next(I).base();
    return true;
  }

  return false;
}

bool Filler::checkRegDefsUses(const BitVector &RegDefs,
                              const BitVector &RegUses,
                              BitVector &NewDefs, BitVector &NewUses,
                              unsigned Reg, bool IsDef) const {
  if (IsDef) {
    NewDefs.set(Reg);
    // check whether Reg has already been defined or used.
    return (isRegInSet(RegDefs, Reg) || isRegInSet(RegUses, Reg));
  }

  NewUses.set(Reg);
  // check whether Reg has already been defined.
  return isRegInSet(RegDefs, Reg);
}

bool Filler::checkRegDefsUses(BitVector &RegDefs, BitVector &RegUses,
                              const MachineInstr &MI, unsigned Begin,
                              unsigned End) const {
  unsigned NumRegs = TM.getRegisterInfo()->getNumRegs();
  BitVector NewDefs(NumRegs), NewUses(NumRegs);
  bool HasHazard = false;

  for (unsigned I = Begin; I != End; ++I) {
    const MachineOperand &MO = MI.getOperand(I);

    if (MO.isReg() && MO.getReg())
      HasHazard |= checkRegDefsUses(RegDefs, RegUses, NewDefs, NewUses,
                                    MO.getReg(), MO.isDef());
  }

  RegDefs |= NewDefs;
  RegUses |= NewUses;

  return HasHazard;
}

bool Filler::delayHasHazard(const MachineInstr &Candidate, bool &SawLoad,
                            bool &SawStore, BitVector &RegDefs,
                            BitVector &RegUses) const {
  bool HasHazard = (Candidate.isImplicitDef() || Candidate.isKill());

  // Loads or stores cannot be moved past a store to the delay slot
  // and stores cannot be moved past a load.
  if (Candidate.mayStore()) {
    HasHazard |= SawStore | SawLoad;
    SawStore = true;
  } else if (Candidate.mayLoad()) {
    HasHazard |= SawStore;
    SawLoad = true;
  }

  assert((!Candidate.isCall() && !Candidate.isReturn()) &&
         "Cannot put calls or returns in delay slot.");

  HasHazard |= checkRegDefsUses(RegDefs, RegUses, Candidate, 0,
                                Candidate.getNumOperands());

  return HasHazard;
}

void Filler::initRegDefsUses(const MachineInstr &MI, BitVector &RegDefs,
                             BitVector &RegUses) const {
  // Add all register operands which are explicit and non-variadic.
  checkRegDefsUses(RegDefs, RegUses, MI, 0, MI.getDesc().getNumOperands());

  // If MI is a call, add RA to RegDefs to prevent users of RA from going into
  // delay slot.
  if (MI.isCall())
    RegDefs.set(Mips::RA);

  // Add all implicit register operands of branch instructions except
  // register AT.
  if (MI.isBranch()) {
    checkRegDefsUses(RegDefs, RegUses, MI, MI.getDesc().getNumOperands(),
                     MI.getNumOperands());
    RegDefs.reset(Mips::AT);
  }
}

//returns true if the Reg or its alias is in the RegSet.
bool Filler::isRegInSet(const BitVector &RegSet, unsigned Reg) const {
  // Check Reg and all aliased Registers.
  for (MCRegAliasIterator AI(Reg, TM.getRegisterInfo(), true);
       AI.isValid(); ++AI)
    if (RegSet.test(*AI))
      return true;
  return false;
}

bool Filler::terminateSearch(const MachineInstr &Candidate) const {
  return (Candidate.isTerminator() || Candidate.isCall() ||
          Candidate.isLabel() || Candidate.isInlineAsm() ||
          Candidate.hasUnmodeledSideEffects());
}
<|endoftext|>


<commit_before>//===-- SparcTargetMachine.cpp - Define TargetMachine for Sparc -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//

#include "SparcTargetAsmInfo.h"
#include "SparcTargetMachine.h"
#include "Sparc.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Target/TargetMachineRegistry.h"
using namespace llvm;

namespace {
  // Register the target.
  RegisterTarget<SparcTargetMachine> X("sparc", "  SPARC");
}

const TargetAsmInfo *SparcTargetMachine::createTargetAsmInfo() const {
  return new SparcTargetAsmInfo(*this);
}

/// SparcTargetMachine ctor - Create an ILP32 architecture model
///
SparcTargetMachine::SparcTargetMachine(const Module &M, const std::string &FS)
  : DataLayout("E-p:32:32"),
    Subtarget(M, FS), InstrInfo(Subtarget),
    FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) {
}

unsigned SparcTargetMachine::getModuleMatchQuality(const Module &M) {
  std::string TT = M.getTargetTriple();
  if (TT.size() >= 6 && std::string(TT.begin(), TT.begin()+6) == "sparc-")
    return 20;

  // If the target triple is something non-sparc, we don't match.
  if (!TT.empty()) return 0;

  if (M.getEndianness()  == Module::BigEndian &&
      M.getPointerSize() == Module::Pointer32)
#ifdef __sparc__
    return 20;   // BE/32 ==> Prefer sparc on sparc
#else
    return 5;    // BE/32 ==> Prefer ppc elsewhere
#endif
  else if (M.getEndianness() != Module::AnyEndianness ||
           M.getPointerSize() != Module::AnyPointerSize)
    return 0;                                    // Match for some other target

  return 0;
}

bool SparcTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
  PM.add(createSparcISelDag(*this));
  return false;
}

/// addPreEmitPass - This pass may be implemented by targets that want to run
/// passes immediately before machine code is emitted.  This should return
/// true if -print-machineinstrs should print out the code after the passes.
bool SparcTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
  PM.add(createSparcFPMoverPass(*this));
  PM.add(createSparcDelaySlotFillerPass(*this));
  return true;
}

bool SparcTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
                                            std::ostream &Out) {
  // Output assembly language.
  PM.add(createSparcCodePrinterPass(Out, *this));
  return false;
}
<commit_msg>Fix an oversight: for modules with no other identifying target info, the sparc backend should be preferred when running on sparcs.<commit_after>//===-- SparcTargetMachine.cpp - Define TargetMachine for Sparc -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//

#include "SparcTargetAsmInfo.h"
#include "SparcTargetMachine.h"
#include "Sparc.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Target/TargetMachineRegistry.h"
using namespace llvm;

namespace {
  // Register the target.
  RegisterTarget<SparcTargetMachine> X("sparc", "  SPARC");
}

const TargetAsmInfo *SparcTargetMachine::createTargetAsmInfo() const {
  return new SparcTargetAsmInfo(*this);
}

/// SparcTargetMachine ctor - Create an ILP32 architecture model
///
SparcTargetMachine::SparcTargetMachine(const Module &M, const std::string &FS)
  : DataLayout("E-p:32:32"),
    Subtarget(M, FS), InstrInfo(Subtarget),
    FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) {
}

unsigned SparcTargetMachine::getModuleMatchQuality(const Module &M) {
  std::string TT = M.getTargetTriple();
  if (TT.size() >= 6 && std::string(TT.begin(), TT.begin()+6) == "sparc-")
    return 20;

  // If the target triple is something non-sparc, we don't match.
  if (!TT.empty()) return 0;

  if (M.getEndianness()  == Module::BigEndian &&
      M.getPointerSize() == Module::Pointer32)
#ifdef __sparc__
    return 20;   // BE/32 ==> Prefer sparc on sparc
#else
    return 5;    // BE/32 ==> Prefer ppc elsewhere
#endif
  else if (M.getEndianness() != Module::AnyEndianness ||
           M.getPointerSize() != Module::AnyPointerSize)
    return 0;                                    // Match for some other target

#if defined(__sparc__)
  return 10;
#else
  return 0;
#endif
}

bool SparcTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
  PM.add(createSparcISelDag(*this));
  return false;
}

/// addPreEmitPass - This pass may be implemented by targets that want to run
/// passes immediately before machine code is emitted.  This should return
/// true if -print-machineinstrs should print out the code after the passes.
bool SparcTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
  PM.add(createSparcFPMoverPass(*this));
  PM.add(createSparcDelaySlotFillerPass(*this));
  return true;
}

bool SparcTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
                                            std::ostream &Out) {
  // Output assembly language.
  PM.add(createSparcCodePrinterPass(Out, *this));
  return false;
}
<|endoftext|>


<commit_before><commit_msg>:construction: chore(hash): updated the implementation of string hashing<commit_after><|endoftext|>


<commit_before>#pragma once
#include "stdafx.h"
#include "cJSON/cJSON.h"

CLANG_DIAGNOSTIC_PUSH;
CLANG_DIAGNOSTIC_IGNORE("-Wunused-macros");

// I dont think namespace matters for macros but whatever
namespace asdf
{
    #define CJSON_GET_INT(int_name)    int_name = cJSON_GetObjectItem(root, #int_name)->valueint;
    #define CJSON_GET_FLOAT(float_name) float_name = static_cast<float>(cJSON_GetObjectItem(root, #float_name)->valuedouble);
    #define CJSON_GET_DOUBLE(int_name) int_name = cJSON_GetObjectItem(root, #int_name)->valuedouble;
    #define CJSON_GET_STR(str_name)    str_name = cJSON_GetObjectItem(root, #str_name)->valuestring;
    #define CJSON_GET_ITEM(obj_name) obj_name.from_JSON(cJSON_GetObjectItem(root, #obj_name));

    #define CJSON_GET_ENUM_INT(int_name, enum_type) int_name = static_cast<enum_type>(cJSON_GetObjectItem(root, #int_name)->valueint);

    #define CJSON_GET_VALUE_ARRAY(container, valuetype, resize_container)     \
        {                                                                     \
            cJSON* container##_json = cJSON_GetObjectItem(root, #container);  \
            size_t len = cJSON_GetArraySize(container##_json);                \
                                                                              \
            if(resize_container)                                              \
            {                                                                 \
                container.clear();                                            \
                container.resize(len);                                        \
            }                                                                 \
            else                                                              \
            {                                                                 \
                ASSERT(container.size() == len, "");                          \
            }                                                                 \
                                                                              \
            for(size_t i = 0; i < len; ++i)                                   \
            {                                                                 \
                cJSON* json = cJSON_GetArrayItem(container##_json, i);        \
                container[i] = json->valuetype;                               \
            }                                                                 \
        }
    //---

    #define CJSON_GET_INT_ARRAY(container)    CJSON_GET_VALUE_ARRAY(container, valueint, false);
    #define CJSON_GET_DOUBLE_ARRAY(container) CJSON_GET_VALUE_ARRAY(container, valuedouble, false);
    #define CJSON_GET_STR_ARRAY(container)    CJSON_GET_VALUE_ARRAY(container, valuestring, false);

    #define CJSON_GET_INT_VECTOR(container)    CJSON_GET_VALUE_ARRAY(container, valueint, true);
    #define CJSON_GET_DOUBLE_VECTOR(container) CJSON_GET_VALUE_ARRAY(container, valuedouble, true);
    #define CJSON_GET_STR_VECTOR(container)    CJSON_GET_VALUE_ARRAY(container, valuestring, true);

    #define CJSON_GET_ITEM_ARRAY(container) \
        {                                                                        \
            cJSON* container##_json = cJSON_GetObjectItem(root, #container);     \
            size_t len = cJSON_GetArraySize(container##_json);                   \
            for(size_t i = 0; i < len; ++i)                                      \
            {                                                                    \
                container[i].from_JSON(cJSON_GetArrayItem(container##_json, i)); \
            }                                                                    \
        }
    //---

    #define CJSON_GET_ITEM_VECTOR(container) \
        { \
            cJSON* container##_json = cJSON_GetObjectItem(root, #container);     \
            size_t len = cJSON_GetArraySize(container##_json);                   \
                                                                                \
            container.clear();                                                   \
            container.resize(len);                                               \
                                                                                \
            for(size_t i = 0; i < len; ++i)                                      \
            {                                                                    \
                container[i].from_JSON(cJSON_GetArrayItem(container##_json, i)); \
            }                                                                    \
        }
    //---

    /*
    */
    #define CJSON_CREATE_ROOT() cJSON* root = cJSON_CreateObject()
    #define CJSON_ADD_BLANK_ITEM(root, child) \
        cJSON* child##_json = cJSON_CreateObject(); \
        cJSON_AddItemToObject(root, #child, child##_json);
    //---
    #define CJSON_ADD_ITEM(obj)  cJSON_AddItemToObject(root, #obj, obj.to_JSON());

    #define CJSON_ADD_NUMBER(num_name)  cJSON_AddNumberToObject(root, #num_name, num_name);
    #define CJSON_ADD_INT(num_name)     CJSON_ADD_NUMBER(num_name)
    #define CJSON_ADD_STR(str_name)     cJSON_AddStringToObject(root, #str_name, (str_name##.c_str() == nullptr) ? "" : str_name##.c_str());
    #define CJSON_ADD_CSTR(str_name)    cJSON_AddStringToObject(root, #str_name, str_name);

    #define CJSON_ITEM_ARRAY(container_name)                              \
        cJSON* container_name##_json = cJSON_CreateArray();               \
        for(auto const& thing : container_name)                           \
        { cJSON_AddItemToArray(container_name##_json, thing.to_JSON()); }
    //---

    #define CJSON_ADD_INT_ARRAY(container)   cJSON_AddItemToObject(root, #container, cJSON_CreateIntArray(container.data(), container.size()));

    #define CJSON_ADD_ITEM_ARRAY(container_name)      \
        CJSON_ITEM_ARRAY(container_name);                       \
        cJSON_AddItemToObject(root, #container_name, container_name##_json);
    //---
}

CLANG_DIAGNOSTIC_POP<commit_msg>updated cjson helper macros (this will probably break stuff)<commit_after>#pragma once
#include "stdafx.h"
#include "cJSON/cJSON.h"

CLANG_DIAGNOSTIC_PUSH;
CLANG_DIAGNOSTIC_IGNORE("-Wunused-macros");

// I dont think namespace matters for macros but whatever
namespace asdf
{
    #define CJSON_OBJ(node_name, obj_name) cJSON_GetObjectItem(node_name, #obj_name)
    #define CJSON_INT(node_name, int_name) CJSON_OBJ(node_name, int_name)->valueint
    #define CJSON_FLOAT(node_name, float_name) static_cast<float>(CJSON_OBJ(node_name, float_name)->valuedouble)
    #define CJSON_DOUBLE(node_name, double_name) CJSON_OBJ(node_name, double_name)->valuedouble
    #define CJSON_STR(node_name, str_name) CJSON_OBJ(node_name, str_name)->valuestring
    #define CJSON_ENUM(node_name, int_name, enum_type) static_cast<enum_type>(CJSON_INT(node_name, int_name))

    #define CJSON_VALUE_ARRAY(container_node, container, valuetype, resize_container)     \
        {                                                                     \
            size_t len = cJSON_GetArraySize(container_node);                  \
                                                                              \
            if(resize_container)                                              \
            {                                                                 \
                container.clear();                                            \
                container.resize(len);                                        \
            }                                                                 \
            else                                                              \
            {                                                                 \
                ASSERT(container.size() == len, "");                          \
            }                                                                 \
                                                                              \
            for(size_t i = 0; i < len; ++i)                                   \
            {                                                                 \
                cJSON* json = cJSON_GetArrayItem(container_node, i);          \
                container[i] = json->valuetype;                               \
            }                                                                 \
        }
    //---

    #define CJSON_GET_INT(int_name)    int_name = CJSON_INT(root, int_name)
    #define CJSON_GET_FLOAT(float_name) float_name = CJSON_FLOAT(root, float_name)
    #define CJSON_GET_DOUBLE(double_name) int_name = CJSON_DOUBLE(root, double_name)
    #define CJSON_GET_STR(str_name)    str_name = CJSON_STR(root, str_name)
    #define CJSON_GET_ITEM(obj_name) obj_name.from_JSON(cJSON_GetObjectItem(root, #obj_name));

    #define CJSON_GET_ENUM_INT(int_name, enum_type) int_name = CJSON_ENUM(int_name, enum_type);

    #define CJSON_GET_VALUE_ARRAY(container, valuetype, resize_container)     \
        {                                                                     \
            cJSON* container_json = cJSON_GetObjectItem(root, #container);  \
            CJSON_VALUE_ARRAY(container_json, container, valuetype, resize_container) \
        }
    //---

    #define CJSON_GET_INT_ARRAY(container)    CJSON_GET_VALUE_ARRAY(container, valueint, false);
    #define CJSON_GET_DOUBLE_ARRAY(container) CJSON_GET_VALUE_ARRAY(container, valuedouble, false);
    #define CJSON_GET_STR_ARRAY(container)    CJSON_GET_VALUE_ARRAY(container, valuestring, false);

    #define CJSON_GET_INT_VECTOR(container)    CJSON_GET_VALUE_ARRAY(container, valueint, true);
    #define CJSON_GET_DOUBLE_VECTOR(container) CJSON_GET_VALUE_ARRAY(container, valuedouble, true);
    #define CJSON_GET_STR_VECTOR(container)    CJSON_GET_VALUE_ARRAY(container, valuestring, true);

    #define CJSON_GET_ITEM_ARRAY(container) \
        {                                                                        \
            cJSON* container##_json = cJSON_GetObjectItem(root, #container);     \
            size_t len = cJSON_GetArraySize(container##_json);                   \
            for(size_t i = 0; i < len; ++i)                                      \
            {                                                                    \
                container[i].from_JSON(cJSON_GetArrayItem(container##_json, i)); \
            }                                                                    \
        }
    //---

    #define CJSON_GET_ITEM_VECTOR(container) \
        { \
            cJSON* container##_json = cJSON_GetObjectItem(root, #container);     \
            size_t len = cJSON_GetArraySize(container##_json);                   \
                                                                                \
            container.clear();                                                   \
            container.resize(len);                                               \
                                                                                \
            for(size_t i = 0; i < len; ++i)                                      \
            {                                                                    \
                container[i].from_JSON(cJSON_GetArrayItem(container##_json, i)); \
            }                                                                    \
        }
    //---

    /*
    */
    #define CJSON_CREATE_ROOT() cJSON* root = cJSON_CreateObject()
    #define CJSON_ADD_BLANK_ITEM(root, child) \
        cJSON* child##_json = cJSON_CreateObject(); \
        cJSON_AddItemToObject(root, #child, child##_json);
    //---
    #define CJSON_ADD_ITEM(obj)  cJSON_AddItemToObject(root, #obj, obj.to_JSON());

    #define CJSON_ADD_NUMBER(num_name)  cJSON_AddNumberToObject(root, #num_name, num_name);
    #define CJSON_ADD_INT(num_name)     CJSON_ADD_NUMBER(num_name)
    #define CJSON_ADD_STR(str_name)     cJSON_AddStringToObject(root, #str_name, (str_name##.c_str() == nullptr) ? "" : str_name##.c_str());
    #define CJSON_ADD_CSTR(str_name)    cJSON_AddStringToObject(root, #str_name, str_name);

    #define CJSON_ITEM_ARRAY(container_name)                              \
        cJSON* container_name##_json = cJSON_CreateArray();               \
        for(auto const& thing : container_name)                           \
        { cJSON_AddItemToArray(container_name##_json, thing.to_JSON()); }
    //---

    #define CJSON_ADD_INT_ARRAY(container)   cJSON_AddItemToObject(root, #container, cJSON_CreateIntArray(container.data(), container.size()));

    #define CJSON_ADD_ITEM_ARRAY(container_name)      \
        CJSON_ITEM_ARRAY(container_name);                       \
        cJSON_AddItemToObject(root, #container_name, container_name##_json);
    //---
}

CLANG_DIAGNOSTIC_POP<|endoftext|>


<commit_before>#include <stdio.h>
#include <string>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <iostream>
#include <vector>

std::string slurp(const std::string &filename) {
  std::ifstream in(filename, std::ifstream::in);
  std::stringstream sstr;
  sstr << in.rdbuf();
  std::string file = sstr.str();
  return file;
}

int main(int argc, char *argv[]) {
  int i = 0, current_row, current_col;
  std::string current_line, current_pos;
  int rows = 4550;
  int column_size = 63;
  // int array[][] = new int[rows][column size]
  std::vector<std::vector<std::string>> data(4551,
                                             std::vector<std::string>(63, ""));
  std::string source_data = slurp("NCI-60.csv");
  std::istringstream source_data_stream(source_data);

  for (current_row = 0; std::getline(source_data_stream, current_line);
       current_row++) {
    std::stringstream row_stream(current_line);
    for (current_col = 0; std::getline(row_stream, current_pos, ',');
         current_col++) {
      data[current_row][current_col] = current_pos;
    }
  }

  std::cout << "Printing last row: ";
  for (current_col = 0; current_col < column_size; current_col++) {
    std::cout << data[4549][current_col] << " ";
  }
  std::cout << std::endl;
}
<commit_msg>vectorize function<commit_after>#include <stdio.h>
#include <string>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <iostream>
#include <vector>

std::string slurp(const std::string &filename) {
  std::ifstream in(filename, std::ifstream::in);
  std::stringstream sstr;
  sstr << in.rdbuf();
  std::string file = sstr.str();
  return file;
}

std::vector<std::vector<std::string>> vectorize(std::string filename, int rows,
                                                int column_size) {
  int current_row, current_col;
  std::string current_line, current_pos;
  std::vector<std::vector<std::string>> data(
      rows, std::vector<std::string>(column_size, ""));
  std::string source_data = slurp(filename);
  std::istringstream source_data_stream(source_data);
  for (current_row = 0; std::getline(source_data_stream, current_line);
       current_row++) {
    std::stringstream row_stream(current_line);
    for (current_col = 0; std::getline(row_stream, current_pos, ',');
         current_col++) {
      data[current_row][current_col] = current_pos;
    }
  }
  return data;
}

int main(int argc, char *argv[]) {
  int current_col, rows = 4550, column_size = 63;
  std::vector<std::vector<std::string>> vector =
      vectorize("NCI-60.csv", rows, column_size);
  std::cout << "Printing last row: ";
  for (current_col = 0; current_col < column_size; current_col++) {
    std::cout << vector[4549][current_col] << " ";
  }
  std::cout << std::endl;
}
<|endoftext|>


<commit_before>#include "ungapped_extension.h"
#include "energy_par.h"
#include "intloops.h"
#include <iostream>

void UngappedExtension::Run(vector<Hit> &candidate, vector<unsigned char> &query_seq, vector<unsigned char> &db_seq, vector<float> &query_accessibility, vector<float> &query_conditional_accessibility, vector<vector<float> > &db_accessibility,vector<vector<float> > &db_conditional_accessibility){
  for(int x = 0; x < candidate.size(); x++){
    double min_energy = candidate[x].GetEnergy();
    double energy = candidate[x].GetEnergy();
    int i = candidate[x].GetQSp(); int p = candidate[x].GetQSp();
    int j = candidate[x].GetDbSp(); int q = candidate[x].GetDbSp();
    int min_p = p; int min_q = q;
    int db_seq_id = candidate[x].GetDbSeqId();
    int db_seq_id_start = candidate[x].GetDbSeqIdStart(); int db_seq_id_end = db_seq_id_start + candidate[x].GetDbLength()-1;
    int min_db_seq_id_start = db_seq_id_start;
    while(true){
      i--; j--;
      db_seq_id_end++;
      if(i < 0 || j < 0 || query_seq[i] < 2 || db_seq[j] < 2){
	break;
      }
      energy += query_accessibility[i] - query_accessibility[i+1] + query_conditional_accessibility[i+_min_accessible_length];
      energy += db_conditional_accessibility[db_seq_id][db_seq_id_end];
      int q_char = query_seq[i] <=5 ? query_seq[i]-1 : query_seq[i]-5;
      int db_char = db_seq[j] <=5 ? db_seq[j]-1 : db_seq[j]-5;
      int type = BP_pair[q_char][db_char];
      if(type!=0){
	int q_char2 = query_seq[p] <=5 ? query_seq[p]-1 : query_seq[p]-5;
	int db_char2 = db_seq[q] <=5 ? db_seq[q]-1 : db_seq[q]-5;
	int type2 = BP_pair[q_char2][db_char2];
	type2 = rtype[type2];
	energy += LoopEnergy(type, type2, i, j, p, q, query_seq, db_seq);
	if(energy < min_energy){
	  min_energy = energy;
	  min_p = i;
	  min_q = j;
	}

	p = i;
	q = j;
      }

      if(min_p-i >= _drop_out_score){
	break;
      }
    }

    energy = min_energy;
    int k = candidate[x].GetQSp() + candidate[x].GetQLength()-1; int r = candidate[x].GetQSp() + candidate[x].GetQLength()-1;
    int l = candidate[x].GetDbSp() + candidate[x].GetQLength()-1; int s = candidate[x].GetDbSp() + candidate[x].GetQLength()-1;
    int min_r = r; int min_s = s;
    while(true){
      k++; l++;
      db_seq_id_start--;
      if(query_seq[k] < 2 || db_seq[l] < 2){
	break;
      }
      energy += query_conditional_accessibility[k];
      energy += db_accessibility[db_seq_id][db_seq_id_start] - db_accessibility[db_seq_id][db_seq_id_start+1] + db_conditional_accessibility[db_seq_id][db_seq_id_start+_min_accessible_length];
      int q_char2 = query_seq[k] <=5 ? query_seq[k]-1 : query_seq[k]-5;
      int db_char2 = db_seq[l] <=5 ? db_seq[l]-1 : db_seq[l]-5;
      int type2 = BP_pair[q_char2][db_char2];
      type2 = rtype[type2];
      if(type2!=0){
	int q_char = query_seq[r] <=5 ? query_seq[r]-1 : query_seq[r]-5;
	int db_char = db_seq[s] <=5 ? db_seq[s]-1 : db_seq[s]-5;
	int type = BP_pair[q_char][db_char];
	energy += LoopEnergy(type, type2, r, s, k, l, query_seq, db_seq);
	if(energy < min_energy){
	  min_energy = energy;
	  min_r = k;
	  min_s = l;
	  min_db_seq_id_start = db_seq_id_start;
	}
	r = k;
	s = l;
      }
      if(k-min_r >= _drop_out_score){
	break;
      }
    }
    candidate[x].SetDbSeqIdStart(min_db_seq_id_start);
    candidate[x].SetQSp(min_p);
    candidate[x].SetDbSp(min_q);
    candidate[x].SetQLength(min_r-min_p+1);
    candidate[x].SetDbLength(min_r-min_p+1);
    candidate[x].SetEnergy(min_energy);
  }
}

double UngappedExtension::LoopEnergy(int type, int type2,int i,int j,int p,int q, vector<unsigned char> &query_seq, vector<unsigned char> &db_seq){
  double z = 0;
  int u1 = p-i-1;
  int u2 = q-j-1;

  if ((u1==0) && (u2==0)){
    z = stack37[type][type2];
  }else{
    int a = query_seq[i+1] <=5 ? query_seq[i+1]-1 : query_seq[i+1]-5;
    int b = db_seq[j+1] <=5 ? db_seq[j+1]-1 : db_seq[j+1]-5;
    int c = query_seq[p-1] <=5 ? query_seq[p-1]-1 : query_seq[p-1]-5;
    int d = db_seq[q-1] <=5 ? db_seq[q-1]-1 : db_seq[q-1]-5;
    if (u1+u2==2) {
      z = int11_37[type][type2][a][b];
    }else if ((u1==1) && (u2==2)){
      z = int21_37[type][type2][a][d][b];
    }else if ((u1==2) && (u2==1)){
      z = int21_37[type2][type][d][a][c];
    }else if ((u1==2) && (u2==2)){
    z = int22_37[type][type2][a][c][d][b];
    }else{
      z = internal_loop37[u1+u2]+mismatchI37[type][a][b]+mismatchI37[type2][d][c];
    }
  }
  return double(z)/100;
}
<commit_msg>Delete ungapped_extension.cpp<commit_after><|endoftext|>