<commit_before>/*! \file */
/* ************************************************************************
 * Copyright (c) 2021 Advanced Micro Devices, Inc.
 *
 * 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.
 *
 * ************************************************************************ */

#include "bsrsm_device.h"
#include "bsrsm_device_large.h"
#include "definitions.h"
#include "rocsparse_bsrsm.hpp"
#include "utility.h"

#define LAUNCH_BSRSM_GTHR_DIM(bsize, wfsize, dim)                 \
    hipLaunchKernelGGL((bsr_gather<wfsize, bsize / wfsize, dim>), \
                       dim3((wfsize * nnzb - 1) / bsize + 1),     \
                       dim3(wfsize, bsize / wfsize),              \
                       0,                                         \
                       stream,                                    \
                       dir,                                       \
                       nnzb,                                      \
                       bsrsm_info->trmt_perm,                     \
                       bsr_val,                                   \
                       bsrt_val,                                  \
                       block_dim)

#define LAUNCH_BSRSM_GTHR(bsize, wfsize, dim) \
    if(dim <= 2)                              \
    {                                         \
        LAUNCH_BSRSM_GTHR_DIM(bsize, 4, 2);   \
    }                                         \
    else if(dim <= 4)                         \
    {                                         \
        LAUNCH_BSRSM_GTHR_DIM(bsize, 16, 4);  \
    }                                         \
    else if(wfsize == 32)                     \
    {                                         \
        LAUNCH_BSRSM_GTHR_DIM(bsize, 16, 4);  \
    }                                         \
    else                                      \
    {                                         \
        LAUNCH_BSRSM_GTHR_DIM(bsize, 64, 8);  \
    }

template <unsigned int BLOCKSIZE, typename T, typename U>
__launch_bounds__(BLOCKSIZE) __global__ void bsrsm_copy_scale(rocsparse_int m,
                                                              rocsparse_int n,
                                                              U             alpha_device_host,
                                                              const T*      B,
                                                              rocsparse_int ldb,
                                                              T*            X,
                                                              rocsparse_int ldx)
{
    auto alpha = load_scalar_device_host(alpha_device_host);

    bsrsm_copy_scale_device(m, n, alpha, B, ldb, X, ldx);
}

template <unsigned int DIM_X, unsigned int DIM_Y, typename T, typename U>
__launch_bounds__(DIM_X* DIM_Y) __global__ void bsrsm_transpose(rocsparse_int m,
                                                                rocsparse_int n,
                                                                U             alpha_device_host,
                                                                const T* __restrict__ A,
                                                                rocsparse_int lda,
                                                                T* __restrict__ B,
                                                                rocsparse_int ldb)
{
    auto alpha = load_scalar_device_host(alpha_device_host);

    dense_transpose_device<DIM_X, DIM_Y>(m, n, alpha, A, lda, B, ldb);
}

template <typename T, typename U>
rocsparse_status rocsparse_bsrsm_solve_template_large(rocsparse_handle          handle,
                                                      rocsparse_direction       dir,
                                                      rocsparse_operation       trans_A,
                                                      rocsparse_operation       trans_X,
                                                      rocsparse_int             mb,
                                                      rocsparse_int             nrhs,
                                                      rocsparse_int             nnzb,
                                                      U                         alpha,
                                                      const rocsparse_mat_descr descr,
                                                      const T*                  bsr_val,
                                                      const rocsparse_int*      bsr_row_ptr,
                                                      const rocsparse_int*      bsr_col_ind,
                                                      rocsparse_int             block_dim,
                                                      rocsparse_mat_info        info,
                                                      const T*                  B,
                                                      rocsparse_int             ldb,
                                                      T*                        X,
                                                      rocsparse_int             ldx,
                                                      void*                     temp_buffer)
{
#define LAUNCH_LARGE_KERNEL(K_, M_, S_)              \
    dim3 bsrsm_blocks(((nrhs - 1) / NCOL + 1) * mb); \
    dim3 bsrsm_threads(NCOL* M_);                    \
    hipLaunchKernelGGL((K_<NCOL * M_, NCOL, S_>),    \
                       bsrsm_blocks,                 \
                       bsrsm_threads,                \
                       0,                            \
                       stream,                       \
                       mb,                           \
                       nrhs,                         \
                       local_bsr_row_ptr,            \
                       local_bsr_col_ind,            \
                       local_bsr_val,                \
                       block_dim,                    \
                       Xt,                           \
                       ldimX,                        \
                       done_array,                   \
                       bsrsm_info->row_map,          \
                       info->zero_pivot,             \
                       descr->base,                  \
                       descr->diag_type,             \
                       dir);

    hipStream_t stream = handle->stream;

    // Buffer
    char* ptr = reinterpret_cast<char*>(temp_buffer);

    ptr += 256;

    // 16 columns per block seem to work very well
    static constexpr unsigned int NCOL = 16;

    int narrays = (nrhs - 1) / NCOL + 1;

    // done_array
    int* done_array = reinterpret_cast<int*>(ptr);
    ptr += sizeof(int) * ((mb * narrays - 1) / 256 + 1) * 256;

    // Temporary array to store transpose of X
    T* Xt = X;
    if(trans_X == rocsparse_operation_none)
    {
        Xt = reinterpret_cast<T*>(ptr);
        ptr += sizeof(T) * ((mb * block_dim * nrhs - 1) / 256 + 1) * 256;
    }

    // Initialize buffers
    RETURN_IF_HIP_ERROR(hipMemsetAsync(done_array, 0, sizeof(int) * mb * narrays, stream));

    rocsparse_trm_info bsrsm_info
        = (descr->fill_mode == rocsparse_fill_mode_upper)
              ? ((trans_A == rocsparse_operation_none) ? info->bsrsm_upper_info
                                                       : info->bsrsmt_upper_info)
              : ((trans_A == rocsparse_operation_none) ? info->bsrsm_lower_info
                                                       : info->bsrsmt_lower_info);

    // If diag type is unit, re-initialize zero pivot to remove structural zeros
    if(descr->diag_type == rocsparse_diag_type_unit)
    {
        rocsparse_int max = std::numeric_limits<rocsparse_int>::max();
        RETURN_IF_HIP_ERROR(hipMemcpyAsync(
            info->zero_pivot, &max, sizeof(rocsparse_int), hipMemcpyHostToDevice, stream));

        // Wait for device transfer to finish
        RETURN_IF_HIP_ERROR(hipStreamSynchronize(stream));
    }

    rocsparse_fill_mode fill_mode = descr->fill_mode;

    // Transpose X if X is not transposed yet to improve performance
    rocsparse_int ldimX = ldx;
    if(trans_X == rocsparse_operation_none)
    {
        // Leading dimension for transposed X
        ldimX = nrhs;

#define BSRSM_DIM_X 32
#define BSRSM_DIM_Y 8
        dim3 bsrsm_blocks((mb * block_dim - 1) / BSRSM_DIM_X + 1);
        dim3 bsrsm_threads(BSRSM_DIM_X * BSRSM_DIM_Y);

        hipLaunchKernelGGL((bsrsm_transpose<BSRSM_DIM_X, BSRSM_DIM_Y>),
                           bsrsm_blocks,
                           bsrsm_threads,
                           0,
                           stream,
                           mb * block_dim,
                           nrhs,
                           alpha,
                           B,
                           ldb,
                           Xt,
                           ldimX);
#undef BSRSM_DIM_X
#undef BSRSM_DIM_Y
    }
    else
    {
        // Copy B into X and scale it with alpha
        hipLaunchKernelGGL((bsrsm_copy_scale<1024>),
                           dim3((mb * block_dim - 1) / 1024 + 1),
                           dim3(1024),
                           0,
                           stream,
                           mb * block_dim,
                           nrhs,
                           alpha,
                           B,
                           ldb,
                           X,
                           ldx);
    }

    // Pointers to differentiate between transpose mode
    const rocsparse_int* local_bsr_row_ptr = bsr_row_ptr;
    const rocsparse_int* local_bsr_col_ind = bsr_col_ind;
    const T*             local_bsr_val     = bsr_val;

    // When computing transposed triangular solve, we first need to update the
    // transposed matrix values
    if(trans_A == rocsparse_operation_transpose)
    {
        T* bsrt_val = reinterpret_cast<T*>(ptr);

        LAUNCH_BSRSM_GTHR(256, 64, block_dim);

        local_bsr_row_ptr = bsrsm_info->trmt_row_ptr;
        local_bsr_col_ind = bsrsm_info->trmt_col_ind;
        local_bsr_val     = bsrt_val;

        fill_mode = (fill_mode == rocsparse_fill_mode_lower) ? rocsparse_fill_mode_upper
                                                             : rocsparse_fill_mode_lower;
    }

    // Determine gcnArch and ASIC revision
    int gcnArch = handle->properties.gcnArch;
    int asicRev = handle->asic_rev;

    // gfx908 A0/1
    if(gcnArch == 908 && asicRev < 2)
    {
        if(fill_mode == rocsparse_fill_mode_upper)
        {
            LAUNCH_LARGE_KERNEL(bsrsm_upper_large_kernel, 16, true);
        }
        else
        {
            LAUNCH_LARGE_KERNEL(bsrsm_lower_large_kernel, 16, true);
        }
    }
    else
    {
        // Select tuned kernel
        unsigned int nbsr = std::max(4U, fnp2(block_dim));

        while(nbsr > 64)
        {
            nbsr >>= 1;
        }

        switch(nbsr)
        {
#define DEFINE_CASE(i)                                               \
    case i:                                                          \
    {                                                                \
        if(fill_mode == rocsparse_fill_mode_upper)                   \
        {                                                            \
            LAUNCH_LARGE_KERNEL(bsrsm_upper_large_kernel, i, false); \
        }                                                            \
        else                                                         \
        {                                                            \
            LAUNCH_LARGE_KERNEL(bsrsm_lower_large_kernel, i, false); \
        }                                                            \
        break;                                                       \
    }

            DEFINE_CASE(4);
            DEFINE_CASE(8);
            DEFINE_CASE(16);
            DEFINE_CASE(32);
            DEFINE_CASE(64);
#undef DEFINE_CASE
        }
    }
#undef LAUNCH_LARGE_KERNEL

    // Transpose X back if X was not initially transposed
    if(trans_X == rocsparse_operation_none)
    {
#define BSRSM_DIM_X 32
#define BSRSM_DIM_Y 8
        dim3 bsrsm_blocks((mb * block_dim - 1) / BSRSM_DIM_X + 1);
        dim3 bsrsm_threads(BSRSM_DIM_X * BSRSM_DIM_Y);

        hipLaunchKernelGGL((dense_transpose_back<BSRSM_DIM_X, BSRSM_DIM_Y>),
                           bsrsm_blocks,
                           bsrsm_threads,
                           0,
                           stream,
                           mb * block_dim,
                           nrhs,
                           Xt,
                           ldimX,
                           X,
                           ldx);
#undef BSRSM_DIM_X
#undef BSRSM_DIM_Y
    }

    return rocsparse_status_success;
}

#define INSTANTIATE(real_type_, scalar_type_)                       \
    template rocsparse_status rocsparse_bsrsm_solve_template_large( \
        rocsparse_handle          handle,                           \
        rocsparse_direction       dir,                              \
        rocsparse_operation       trans_A,                          \
        rocsparse_operation       trans_X,                          \
        rocsparse_int             mb,                               \
        rocsparse_int             nrhs,                             \
        rocsparse_int             nnzb,                             \
        scalar_type_              alpha,                            \
        const rocsparse_mat_descr descr,                            \
        const real_type_*         bsr_val,                          \
        const rocsparse_int*      bsr_row_ptr,                      \
        const rocsparse_int*      bsr_col_ind,                      \
        rocsparse_int             block_dim,                        \
        rocsparse_mat_info        info,                             \
        const real_type_*         B,                                \
        rocsparse_int             ldb,                              \
        real_type_*               X,                                \
        rocsparse_int             ldx,                              \
        void*                     temp_buffer)

INSTANTIATE(float, float);
INSTANTIATE(float, const float*);

INSTANTIATE(double, double);
INSTANTIATE(double, const double*);

INSTANTIATE(rocsparse_float_complex, rocsparse_float_complex);
INSTANTIATE(rocsparse_float_complex, const rocsparse_float_complex*);

INSTANTIATE(rocsparse_double_complex, rocsparse_double_complex);
INSTANTIATE(rocsparse_double_complex, const rocsparse_double_complex*);
#undef INSTANTIATE
<commit_msg>navi21 fix for bsrsm (#237)<commit_after>/*! \file */
/* ************************************************************************
 * Copyright (c) 2021 Advanced Micro Devices, Inc.
 *
 * 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.
 *
 * ************************************************************************ */

#include "bsrsm_device.h"
#include "bsrsm_device_large.h"
#include "definitions.h"
#include "rocsparse_bsrsm.hpp"
#include "utility.h"

#define LAUNCH_BSRSM_GTHR_DIM(bsize, wfsize, dim)                 \
    hipLaunchKernelGGL((bsr_gather<wfsize, bsize / wfsize, dim>), \
                       dim3((wfsize * nnzb - 1) / bsize + 1),     \
                       dim3(wfsize, bsize / wfsize),              \
                       0,                                         \
                       stream,                                    \
                       dir,                                       \
                       nnzb,                                      \
                       bsrsm_info->trmt_perm,                     \
                       bsr_val,                                   \
                       bsrt_val,                                  \
                       block_dim)

#define LAUNCH_BSRSM_GTHR(bsize, wfsize, dim) \
    if(dim <= 2)                              \
    {                                         \
        LAUNCH_BSRSM_GTHR_DIM(bsize, 4, 2);   \
    }                                         \
    else if(dim <= 4)                         \
    {                                         \
        LAUNCH_BSRSM_GTHR_DIM(bsize, 16, 4);  \
    }                                         \
    else if(wfsize == 32)                     \
    {                                         \
        LAUNCH_BSRSM_GTHR_DIM(bsize, 16, 4);  \
    }                                         \
    else                                      \
    {                                         \
        LAUNCH_BSRSM_GTHR_DIM(bsize, 64, 8);  \
    }

template <unsigned int BLOCKSIZE, typename T, typename U>
__launch_bounds__(BLOCKSIZE) __global__ void bsrsm_copy_scale(rocsparse_int m,
                                                              rocsparse_int n,
                                                              U             alpha_device_host,
                                                              const T*      B,
                                                              rocsparse_int ldb,
                                                              T*            X,
                                                              rocsparse_int ldx)
{
    auto alpha = load_scalar_device_host(alpha_device_host);

    bsrsm_copy_scale_device(m, n, alpha, B, ldb, X, ldx);
}

template <unsigned int DIM_X, unsigned int DIM_Y, typename T, typename U>
__launch_bounds__(DIM_X* DIM_Y) __global__ void bsrsm_transpose(rocsparse_int m,
                                                                rocsparse_int n,
                                                                U             alpha_device_host,
                                                                const T* __restrict__ A,
                                                                rocsparse_int lda,
                                                                T* __restrict__ B,
                                                                rocsparse_int ldb)
{
    auto alpha = load_scalar_device_host(alpha_device_host);

    dense_transpose_device<DIM_X, DIM_Y>(m, n, alpha, A, lda, B, ldb);
}

template <typename T, typename U>
rocsparse_status rocsparse_bsrsm_solve_template_large(rocsparse_handle          handle,
                                                      rocsparse_direction       dir,
                                                      rocsparse_operation       trans_A,
                                                      rocsparse_operation       trans_X,
                                                      rocsparse_int             mb,
                                                      rocsparse_int             nrhs,
                                                      rocsparse_int             nnzb,
                                                      U                         alpha,
                                                      const rocsparse_mat_descr descr,
                                                      const T*                  bsr_val,
                                                      const rocsparse_int*      bsr_row_ptr,
                                                      const rocsparse_int*      bsr_col_ind,
                                                      rocsparse_int             block_dim,
                                                      rocsparse_mat_info        info,
                                                      const T*                  B,
                                                      rocsparse_int             ldb,
                                                      T*                        X,
                                                      rocsparse_int             ldx,
                                                      void*                     temp_buffer)
{
#define LAUNCH_LARGE_KERNEL(K_, M_, S_)              \
    dim3 bsrsm_blocks(((nrhs - 1) / NCOL + 1) * mb); \
    dim3 bsrsm_threads(NCOL* M_);                    \
    hipLaunchKernelGGL((K_<NCOL * M_, NCOL, S_>),    \
                       bsrsm_blocks,                 \
                       bsrsm_threads,                \
                       0,                            \
                       stream,                       \
                       mb,                           \
                       nrhs,                         \
                       local_bsr_row_ptr,            \
                       local_bsr_col_ind,            \
                       local_bsr_val,                \
                       block_dim,                    \
                       Xt,                           \
                       ldimX,                        \
                       done_array,                   \
                       bsrsm_info->row_map,          \
                       info->zero_pivot,             \
                       descr->base,                  \
                       descr->diag_type,             \
                       dir);

    hipStream_t stream = handle->stream;

    // Buffer
    char* ptr = reinterpret_cast<char*>(temp_buffer);

    ptr += 256;

    // 16 columns per block seem to work very well
    static constexpr unsigned int NCOL = 16;

    int narrays = (nrhs - 1) / NCOL + 1;

    // done_array
    int* done_array = reinterpret_cast<int*>(ptr);
    ptr += sizeof(int) * ((mb * narrays - 1) / 256 + 1) * 256;

    // Temporary array to store transpose of X
    T* Xt = X;
    if(trans_X == rocsparse_operation_none)
    {
        Xt = reinterpret_cast<T*>(ptr);
        ptr += sizeof(T) * ((mb * block_dim * nrhs - 1) / 256 + 1) * 256;
    }

    // Initialize buffers
    RETURN_IF_HIP_ERROR(hipMemsetAsync(done_array, 0, sizeof(int) * mb * narrays, stream));

    rocsparse_trm_info bsrsm_info
        = (descr->fill_mode == rocsparse_fill_mode_upper)
              ? ((trans_A == rocsparse_operation_none) ? info->bsrsm_upper_info
                                                       : info->bsrsmt_upper_info)
              : ((trans_A == rocsparse_operation_none) ? info->bsrsm_lower_info
                                                       : info->bsrsmt_lower_info);

    // If diag type is unit, re-initialize zero pivot to remove structural zeros
    if(descr->diag_type == rocsparse_diag_type_unit)
    {
        rocsparse_int max = std::numeric_limits<rocsparse_int>::max();
        RETURN_IF_HIP_ERROR(hipMemcpyAsync(
            info->zero_pivot, &max, sizeof(rocsparse_int), hipMemcpyHostToDevice, stream));

        // Wait for device transfer to finish
        RETURN_IF_HIP_ERROR(hipStreamSynchronize(stream));
    }

    rocsparse_fill_mode fill_mode = descr->fill_mode;

    // Transpose X if X is not transposed yet to improve performance
    rocsparse_int ldimX = ldx;
    if(trans_X == rocsparse_operation_none)
    {
        // Leading dimension for transposed X
        ldimX = nrhs;

#define BSRSM_DIM_X 32
#define BSRSM_DIM_Y 8
        dim3 bsrsm_blocks((mb * block_dim - 1) / BSRSM_DIM_X + 1);
        dim3 bsrsm_threads(BSRSM_DIM_X * BSRSM_DIM_Y);

        hipLaunchKernelGGL((bsrsm_transpose<BSRSM_DIM_X, BSRSM_DIM_Y>),
                           bsrsm_blocks,
                           bsrsm_threads,
                           0,
                           stream,
                           mb * block_dim,
                           nrhs,
                           alpha,
                           B,
                           ldb,
                           Xt,
                           ldimX);
#undef BSRSM_DIM_X
#undef BSRSM_DIM_Y
    }
    else
    {
        // Copy B into X and scale it with alpha
        hipLaunchKernelGGL((bsrsm_copy_scale<1024>),
                           dim3((mb * block_dim - 1) / 1024 + 1),
                           dim3(1024),
                           0,
                           stream,
                           mb * block_dim,
                           nrhs,
                           alpha,
                           B,
                           ldb,
                           X,
                           ldx);
    }

    // Pointers to differentiate between transpose mode
    const rocsparse_int* local_bsr_row_ptr = bsr_row_ptr;
    const rocsparse_int* local_bsr_col_ind = bsr_col_ind;
    const T*             local_bsr_val     = bsr_val;

    // When computing transposed triangular solve, we first need to update the
    // transposed matrix values
    if(trans_A == rocsparse_operation_transpose)
    {
        T* bsrt_val = reinterpret_cast<T*>(ptr);

        LAUNCH_BSRSM_GTHR(256, 64, block_dim);

        local_bsr_row_ptr = bsrsm_info->trmt_row_ptr;
        local_bsr_col_ind = bsrsm_info->trmt_col_ind;
        local_bsr_val     = bsrt_val;

        fill_mode = (fill_mode == rocsparse_fill_mode_lower) ? rocsparse_fill_mode_upper
                                                             : rocsparse_fill_mode_lower;
    }

    // Determine gcnArch and ASIC revision
    int gcnArch = handle->properties.gcnArch;
    int asicRev = handle->asic_rev;
    int wfSize  = handle->wavefront_size;

    // gfx908 A0/1
    if(gcnArch == 908 && asicRev < 2)
    {
        if(fill_mode == rocsparse_fill_mode_upper)
        {
            LAUNCH_LARGE_KERNEL(bsrsm_upper_large_kernel, 16, true);
        }
        else
        {
            LAUNCH_LARGE_KERNEL(bsrsm_lower_large_kernel, 16, true);
        }
    }
    else
    {
        // Select tuned kernel
        unsigned int nbsr = std::max(4U, fnp2(block_dim));

        while(nbsr > wfSize)
        {
            nbsr >>= 1;
        }

        switch(nbsr)
        {
#define DEFINE_CASE(i)                                               \
    case i:                                                          \
    {                                                                \
        if(fill_mode == rocsparse_fill_mode_upper)                   \
        {                                                            \
            LAUNCH_LARGE_KERNEL(bsrsm_upper_large_kernel, i, false); \
        }                                                            \
        else                                                         \
        {                                                            \
            LAUNCH_LARGE_KERNEL(bsrsm_lower_large_kernel, i, false); \
        }                                                            \
        break;                                                       \
    }

            DEFINE_CASE(4);
            DEFINE_CASE(8);
            DEFINE_CASE(16);
            DEFINE_CASE(32);
            DEFINE_CASE(64);
#undef DEFINE_CASE
        }
    }
#undef LAUNCH_LARGE_KERNEL

    // Transpose X back if X was not initially transposed
    if(trans_X == rocsparse_operation_none)
    {
#define BSRSM_DIM_X 32
#define BSRSM_DIM_Y 8
        dim3 bsrsm_blocks((mb * block_dim - 1) / BSRSM_DIM_X + 1);
        dim3 bsrsm_threads(BSRSM_DIM_X * BSRSM_DIM_Y);

        hipLaunchKernelGGL((dense_transpose_back<BSRSM_DIM_X, BSRSM_DIM_Y>),
                           bsrsm_blocks,
                           bsrsm_threads,
                           0,
                           stream,
                           mb * block_dim,
                           nrhs,
                           Xt,
                           ldimX,
                           X,
                           ldx);
#undef BSRSM_DIM_X
#undef BSRSM_DIM_Y
    }

    return rocsparse_status_success;
}

#define INSTANTIATE(real_type_, scalar_type_)                       \
    template rocsparse_status rocsparse_bsrsm_solve_template_large( \
        rocsparse_handle          handle,                           \
        rocsparse_direction       dir,                              \
        rocsparse_operation       trans_A,                          \
        rocsparse_operation       trans_X,                          \
        rocsparse_int             mb,                               \
        rocsparse_int             nrhs,                             \
        rocsparse_int             nnzb,                             \
        scalar_type_              alpha,                            \
        const rocsparse_mat_descr descr,                            \
        const real_type_*         bsr_val,                          \
        const rocsparse_int*      bsr_row_ptr,                      \
        const rocsparse_int*      bsr_col_ind,                      \
        rocsparse_int             block_dim,                        \
        rocsparse_mat_info        info,                             \
        const real_type_*         B,                                \
        rocsparse_int             ldb,                              \
        real_type_*               X,                                \
        rocsparse_int             ldx,                              \
        void*                     temp_buffer)

INSTANTIATE(float, float);
INSTANTIATE(float, const float*);

INSTANTIATE(double, double);
INSTANTIATE(double, const double*);

INSTANTIATE(rocsparse_float_complex, rocsparse_float_complex);
INSTANTIATE(rocsparse_float_complex, const rocsparse_float_complex*);

INSTANTIATE(rocsparse_double_complex, rocsparse_double_complex);
INSTANTIATE(rocsparse_double_complex, const rocsparse_double_complex*);
#undef INSTANTIATE
<|endoftext|>


<commit_before>/*
    Copyright (C) 2008 by Frank Richter

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"

#include "csplugincommon/rendermanager/autofx_reflrefr.h"

#include "csutil/cfgacc.h"
#include "csutil/objreg.h"
#include "imap/loader.h"

namespace CS
{
  namespace RenderManager
  {
#define AFRRBPD   AutoFX_ReflectRefract_Base::PersistentData

    AFRRBPD::PersistentData() :
      currentFrame (0),
      texCache (csimg2D, "rgb8",  // @@@ FIXME: Use same format as main view ...
	CS_TEXTURE_3D | CS_TEXTURE_NOMIPMAPS | CS_TEXTURE_CLAMP
	  | CS_TEXTURE_NPOTS | CS_TEXTURE_CLAMP | CS_TEXTURE_SCALE_UP,
	"target", 0,
	CS::Utility::ResourceCache::ReuseIfOnlyOneRef ()),
      texCacheDepth (csimg2D, "d32",
	CS_TEXTURE_3D | CS_TEXTURE_NOMIPMAPS | CS_TEXTURE_CLAMP
	  | CS_TEXTURE_NPOTS | CS_TEXTURE_CLAMP | CS_TEXTURE_SCALE_UP,
	"target", 0,
	CS::Utility::ResourceCache::ReuseIfOnlyOneRef ())
    {
    }

    void AFRRBPD::Initialize (iObjectRegistry* objReg,
		              RenderTreeBase::DebugPersistent& dbgPersist,
		              PostEffectManager* postEffects)
    {
      dbgReflRefrTex = dbgPersist.RegisterDebugFlag ("textures.reflrefr");

      csRef<iShaderManager> shaderManager =
	csQueryRegistry<iShaderManager> (objReg);

      iShaderVarStringSet* strings = shaderManager->GetSVNameStringset();
      svTexPlaneRefl = strings->Request ("tex plane reflect");
      svTexPlaneRefr = strings->Request ("tex plane refract");
      svTexPlaneReflDepth = strings->Request ("tex plane reflect depth");
      svTexPlaneRefrDepth = strings->Request ("tex plane refract depth");

      svPlaneRefl = strings->Request ("plane reflection");
      svClipPlaneReflRefr = strings->Request ("clip plane reflection");

      csConfigAccess config (objReg);
      resolutionReduceRefl = config->GetInt (
	"RenderManager.Reflections.Downsample", 1);
      resolutionReduceRefr = config->GetInt (
	"RenderManager.Refractions.Downsample", resolutionReduceRefl);
      texUpdateInterval = config->GetInt (
	"RenderManager.Reflections.UpdateInterval", 0);
      maxUpdatesPerFrame = config->GetInt (
	"RenderManager.Reflections.MaxUpdatesPerFrame", 0);
      mappingStretch = config->GetFloat (
	"RenderManager.Reflections.MappingStretch", 1.0f);
      cameraChangeThresh = config->GetFloat (
	"RenderManager.Reflections.CameraChangeThreshold", 0.01f);

      svReflXform = strings->Request ("reflection coord xform");
      reflXformSV.AttachNew (new csShaderVariable (svReflXform));
      screenFlipped = postEffects ? postEffects->ScreenSpaceYFlipped() : false;

      csRef<iGraphics3D> g3d = csQueryRegistry<iGraphics3D> (objReg);
      texCache.SetG3D (g3d);
      texCacheDepth.SetG3D (g3d);
    }

    void AFRRBPD::UpdateNewFrame ()
    {
      csTicks currentTicks = csGetTicks ();
      ReflRefrCache::GlobalIterator reflRefrIt (
	reflRefrCache.GetIterator ());
      while (reflRefrIt.HasNext())
      {
	ReflectRefractSVs& meshReflectRefract = reflRefrIt.NextNoAdvance();
	// Don't remove if update interval hasn't passed yet
	if ((texUpdateInterval > 0)
	  && ((currentTicks - meshReflectRefract.lastUpdate) <=
	    texUpdateInterval))
	{
	  reflRefrIt.Next();
	  continue;
	}
	// Don't remove if not in line for round-robin update
	if ((maxUpdatesPerFrame > 0)
	  && (currentFrame - meshReflectRefract.lastUpdateFrame <
	    ((reflRefrCache.GetSize()+maxUpdatesPerFrame-1) / maxUpdatesPerFrame)))
	{
	  reflRefrIt.Next();
	  continue;
	}
	reflRefrCache.DeleteElement (reflRefrIt);
      }

      currentFrame++;
      updatesThisFrame = 0;

      texCache.AdvanceFrame (currentTicks);
      texCacheDepth.AdvanceFrame (currentTicks);
    }
  } // namespace RenderManager
} // namespace CS
<commit_msg>- Added CS_TEXTURE_NOFILTER flag to water depth texture. Fixes issues with pre-GF8 cards.<commit_after>/*
    Copyright (C) 2008 by Frank Richter

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"

#include "csplugincommon/rendermanager/autofx_reflrefr.h"

#include "csutil/cfgacc.h"
#include "csutil/objreg.h"
#include "imap/loader.h"

namespace CS
{
  namespace RenderManager
  {
#define AFRRBPD   AutoFX_ReflectRefract_Base::PersistentData

    AFRRBPD::PersistentData() :
      currentFrame (0),
      texCache (csimg2D, "rgb8",  // @@@ FIXME: Use same format as main view ...
	CS_TEXTURE_3D | CS_TEXTURE_NOMIPMAPS | CS_TEXTURE_CLAMP
	  | CS_TEXTURE_NPOTS | CS_TEXTURE_CLAMP | CS_TEXTURE_SCALE_UP,
	"target", 0,
	CS::Utility::ResourceCache::ReuseIfOnlyOneRef ()),
      texCacheDepth (csimg2D, "d32",
	CS_TEXTURE_3D | CS_TEXTURE_NOMIPMAPS | CS_TEXTURE_CLAMP
	  | CS_TEXTURE_NPOTS | CS_TEXTURE_CLAMP | CS_TEXTURE_SCALE_UP | CS_TEXTURE_NOFILTER,
	"target", 0,
	CS::Utility::ResourceCache::ReuseIfOnlyOneRef ())
    {
    }

    void AFRRBPD::Initialize (iObjectRegistry* objReg,
		              RenderTreeBase::DebugPersistent& dbgPersist,
		              PostEffectManager* postEffects)
    {
      dbgReflRefrTex = dbgPersist.RegisterDebugFlag ("textures.reflrefr");

      csRef<iShaderManager> shaderManager =
	csQueryRegistry<iShaderManager> (objReg);

      iShaderVarStringSet* strings = shaderManager->GetSVNameStringset();
      svTexPlaneRefl = strings->Request ("tex plane reflect");
      svTexPlaneRefr = strings->Request ("tex plane refract");
      svTexPlaneReflDepth = strings->Request ("tex plane reflect depth");
      svTexPlaneRefrDepth = strings->Request ("tex plane refract depth");

      svPlaneRefl = strings->Request ("plane reflection");
      svClipPlaneReflRefr = strings->Request ("clip plane reflection");

      csConfigAccess config (objReg);
      resolutionReduceRefl = config->GetInt (
	"RenderManager.Reflections.Downsample", 1);
      resolutionReduceRefr = config->GetInt (
	"RenderManager.Refractions.Downsample", resolutionReduceRefl);
      texUpdateInterval = config->GetInt (
	"RenderManager.Reflections.UpdateInterval", 0);
      maxUpdatesPerFrame = config->GetInt (
	"RenderManager.Reflections.MaxUpdatesPerFrame", 0);
      mappingStretch = config->GetFloat (
	"RenderManager.Reflections.MappingStretch", 1.0f);
      cameraChangeThresh = config->GetFloat (
	"RenderManager.Reflections.CameraChangeThreshold", 0.01f);

      svReflXform = strings->Request ("reflection coord xform");
      reflXformSV.AttachNew (new csShaderVariable (svReflXform));
      screenFlipped = postEffects ? postEffects->ScreenSpaceYFlipped() : false;

      csRef<iGraphics3D> g3d = csQueryRegistry<iGraphics3D> (objReg);
      texCache.SetG3D (g3d);
      texCacheDepth.SetG3D (g3d);
    }

    void AFRRBPD::UpdateNewFrame ()
    {
      csTicks currentTicks = csGetTicks ();
      ReflRefrCache::GlobalIterator reflRefrIt (
	reflRefrCache.GetIterator ());
      while (reflRefrIt.HasNext())
      {
	ReflectRefractSVs& meshReflectRefract = reflRefrIt.NextNoAdvance();
	// Don't remove if update interval hasn't passed yet
	if ((texUpdateInterval > 0)
	  && ((currentTicks - meshReflectRefract.lastUpdate) <=
	    texUpdateInterval))
	{
	  reflRefrIt.Next();
	  continue;
	}
	// Don't remove if not in line for round-robin update
	if ((maxUpdatesPerFrame > 0)
	  && (currentFrame - meshReflectRefract.lastUpdateFrame <
	    ((reflRefrCache.GetSize()+maxUpdatesPerFrame-1) / maxUpdatesPerFrame)))
	{
	  reflRefrIt.Next();
	  continue;
	}
	reflRefrCache.DeleteElement (reflRefrIt);
      }

      currentFrame++;
      updatesThisFrame = 0;

      texCache.AdvanceFrame (currentTicks);
      texCacheDepth.AdvanceFrame (currentTicks);
    }
  } // namespace RenderManager
} // namespace CS
<|endoftext|>


<commit_before>/*
 *  This file is part of Poedit (https://poedit.net)
 *
 *  Copyright (C) 2000-2017 Vaclav Slavik
 *
 *  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.
 *
 */

#include "cat_update.h"

#include "extractors/extractor.h"
#include "progressinfo.h"
#include "utility.h"

#include <wx/config.h>
#include <wx/dialog.h>
#include <wx/intl.h>
#include <wx/listbox.h>
#include <wx/log.h>
#include <wx/stattext.h>
#include <wx/xrc/xmlres.h>

namespace
{

/** This class provides simple dialog that displays list
  * of changes made in the catalog.
  */
class MergeSummaryDialog : public wxDialog
{
    public:
        MergeSummaryDialog(wxWindow *parent);
        ~MergeSummaryDialog();

        /** Reads data from catalog and fill dialog's controls.
            \param snew      list of strings that are new to the catalog
            \param sobsolete list of strings that no longer appear in the
                             catalog (as compared to catalog's state before
                             parsing sources).
         */
        void TransferTo(const wxArrayString& snew,
                        const wxArrayString& sobsolete);
};

MergeSummaryDialog::MergeSummaryDialog(wxWindow *parent)
{
    wxXmlResource::Get()->LoadDialog(this, parent, "summary");

    RestoreWindowState(this, wxDefaultSize, WinState_Size);
    CentreOnParent();
}

MergeSummaryDialog::~MergeSummaryDialog()
{
    SaveWindowState(this, WinState_Size);
}

void MergeSummaryDialog::TransferTo(const wxArrayString& snew, const wxArrayString& sobsolete)
{
    wxString sum;
    sum.Printf(_("(New: %i, obsolete: %i)"),
               (int)snew.GetCount(), (int)sobsolete.GetCount());
    XRCCTRL(*this, "items_count", wxStaticText)->SetLabel(sum);

    wxListBox *listbox;
    size_t i;

    listbox = XRCCTRL(*this, "new_strings", wxListBox);
    for (i = 0; i < snew.GetCount(); i++)
    {
        listbox->Append(snew[i]);
    }

    listbox = XRCCTRL(*this, "obsolete_strings", wxListBox);
    for (i = 0; i < sobsolete.GetCount(); i++)
    {
        listbox->Append(sobsolete[i]);
    }
}

inline wxString ItemMergeSummary(const CatalogItemPtr& item)
{
    wxString s = item->GetString();
    if ( item->HasPlural() )
        s += "|" + item->GetPluralString();
    if ( item->HasContext() )
        s += wxString::Format(" [%s]", item->GetContext());

    return s;
}

/** Returns list of strings that are new in reference catalog
    (compared to this one) and that are not present in \a refcat
    (i.e. are obsoleted).

    \see ShowMergeSummary
 */
void GetMergeSummary(CatalogPtr po, CatalogPtr refcat,
                     wxArrayString& snew, wxArrayString& sobsolete)
{
    wxASSERT( snew.empty() );
    wxASSERT( sobsolete.empty() );

    std::set<wxString> strsThis, strsRef;

    for (auto& i: po->items())
        strsThis.insert(ItemMergeSummary(i));
    for (auto& i: refcat->items())
        strsRef.insert(ItemMergeSummary(i));

    for (auto& i: strsThis)
    {
        if (strsRef.find(i) == strsRef.end())
            sobsolete.Add(i);
    }

    for (auto& i: strsRef)
    {
        if (strsThis.find(i) == strsThis.end())
            snew.Add(i);
    }
}

/** Shows a dialog with merge summary.
    \see GetMergeSummary, Merge

    \return true if the merge was OK'ed by the user, false otherwise
 */
bool ShowMergeSummary(wxWindow *parent, ProgressInfo *progress, CatalogPtr po, CatalogPtr refcat, bool *cancelledByUser)
{
    if (cancelledByUser)
        *cancelledByUser = false;
    if (wxConfig::Get()->ReadBool("show_summary", false))
    {
        wxArrayString snew, sobsolete;
        GetMergeSummary(po, refcat, snew, sobsolete);
        MergeSummaryDialog sdlg(parent);
        sdlg.TransferTo(snew, sobsolete);

        if (progress)
            progress->Hide();
        bool ok = (sdlg.ShowModal() == wxID_OK);
        if (progress)
            progress->Show();

        if (cancelledByUser)
            *cancelledByUser = !ok;
        return ok;
    }
    else
        return true;
}

} // anonymous namespace

bool PerformUpdateFromSources(wxWindow *parent,
                              CatalogPtr catalog,
                              UpdateResultReason& reason,
                              int flags)
{
    const bool skipSummary = (flags & Update_DontShowSummary);

    ProgressInfo progress(parent, _("Updating catalog"));

    reason = UpdateResultReason::Unspecified;
    if (!catalog->IsOk())
        return false;

    auto spec = catalog->GetSourceCodeSpec();
    if (!spec)
    {
        reason = UpdateResultReason::NoSourcesFound;
        return false;
    }

    CatalogPtr pot = nullptr;

    progress.UpdateMessage(_("Scanning files..."));
    progress.PulseGauge();

    auto files = Extractor::CollectAllFiles(*spec);

    if (!files.empty())
    {
        TempDirectory tmpdir;
        auto potFile = Extractor::ExtractWithAll(tmpdir, *spec, files);
        if (!potFile.empty())
        {
            pot = std::make_shared<Catalog>(potFile, Catalog::CreationFlag_IgnoreHeader);
            if (!pot->IsOk())
            {
                wxLogError(_("Failed to load extracted catalog."));
                pot.reset();
            }
        }
    }
    else
    {
        reason = UpdateResultReason::NoSourcesFound;
    }

    if (progress.Cancelled())
    {
        reason = UpdateResultReason::CancelledByUser;
        return false;
    }

    if (!pot)
        return false;

    progress.UpdateMessage(_("Merging differences..."));

    bool succ = false;
    bool cancelledByUser = false;
    if (skipSummary || ShowMergeSummary(parent, &progress, catalog, pot, &cancelledByUser))
    {
        succ = catalog->UpdateFromPOT(pot);
    }

    if (cancelledByUser)
        reason = UpdateResultReason::CancelledByUser;

    return succ;
}

bool PerformUpdateFromPOT(wxWindow *parent,
                          CatalogPtr catalog,
                          const wxString& pot_file,
                          UpdateResultReason& reason)
{
    reason = UpdateResultReason::Unspecified;
    if (!catalog->IsOk())
        return false;

    CatalogPtr pot = std::make_shared<Catalog>(pot_file, Catalog::CreationFlag_IgnoreTranslations);

    if (!pot->IsOk())
    {
        wxLogError(_("'%s' is not a valid POT file."), pot_file.c_str());
        return false;
    }

    bool cancelledByUser = false;
    if (ShowMergeSummary(parent, nullptr, catalog, pot, &cancelledByUser))
    {
        return catalog->UpdateFromPOT(pot);
    }
    else
    {
        if (cancelledByUser)
            reason = UpdateResultReason::CancelledByUser;
        return false;
    }
}
<commit_msg>More granular, better progress messages during update<commit_after>/*
 *  This file is part of Poedit (https://poedit.net)
 *
 *  Copyright (C) 2000-2017 Vaclav Slavik
 *
 *  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.
 *
 */

#include "cat_update.h"

#include "extractors/extractor.h"
#include "progressinfo.h"
#include "utility.h"

#include <wx/config.h>
#include <wx/dialog.h>
#include <wx/intl.h>
#include <wx/listbox.h>
#include <wx/log.h>
#include <wx/stattext.h>
#include <wx/xrc/xmlres.h>

namespace
{

/** This class provides simple dialog that displays list
  * of changes made in the catalog.
  */
class MergeSummaryDialog : public wxDialog
{
    public:
        MergeSummaryDialog(wxWindow *parent);
        ~MergeSummaryDialog();

        /** Reads data from catalog and fill dialog's controls.
            \param snew      list of strings that are new to the catalog
            \param sobsolete list of strings that no longer appear in the
                             catalog (as compared to catalog's state before
                             parsing sources).
         */
        void TransferTo(const wxArrayString& snew,
                        const wxArrayString& sobsolete);
};

MergeSummaryDialog::MergeSummaryDialog(wxWindow *parent)
{
    wxXmlResource::Get()->LoadDialog(this, parent, "summary");

    RestoreWindowState(this, wxDefaultSize, WinState_Size);
    CentreOnParent();
}

MergeSummaryDialog::~MergeSummaryDialog()
{
    SaveWindowState(this, WinState_Size);
}

void MergeSummaryDialog::TransferTo(const wxArrayString& snew, const wxArrayString& sobsolete)
{
    wxString sum;
    sum.Printf(_("(New: %i, obsolete: %i)"),
               (int)snew.GetCount(), (int)sobsolete.GetCount());
    XRCCTRL(*this, "items_count", wxStaticText)->SetLabel(sum);

    wxListBox *listbox;
    size_t i;

    listbox = XRCCTRL(*this, "new_strings", wxListBox);
    for (i = 0; i < snew.GetCount(); i++)
    {
        listbox->Append(snew[i]);
    }

    listbox = XRCCTRL(*this, "obsolete_strings", wxListBox);
    for (i = 0; i < sobsolete.GetCount(); i++)
    {
        listbox->Append(sobsolete[i]);
    }
}

inline wxString ItemMergeSummary(const CatalogItemPtr& item)
{
    wxString s = item->GetString();
    if ( item->HasPlural() )
        s += "|" + item->GetPluralString();
    if ( item->HasContext() )
        s += wxString::Format(" [%s]", item->GetContext());

    return s;
}

/** Returns list of strings that are new in reference catalog
    (compared to this one) and that are not present in \a refcat
    (i.e. are obsoleted).

    \see ShowMergeSummary
 */
void GetMergeSummary(CatalogPtr po, CatalogPtr refcat,
                     wxArrayString& snew, wxArrayString& sobsolete)
{
    wxASSERT( snew.empty() );
    wxASSERT( sobsolete.empty() );

    std::set<wxString> strsThis, strsRef;

    for (auto& i: po->items())
        strsThis.insert(ItemMergeSummary(i));
    for (auto& i: refcat->items())
        strsRef.insert(ItemMergeSummary(i));

    for (auto& i: strsThis)
    {
        if (strsRef.find(i) == strsRef.end())
            sobsolete.Add(i);
    }

    for (auto& i: strsRef)
    {
        if (strsThis.find(i) == strsThis.end())
            snew.Add(i);
    }
}

/** Shows a dialog with merge summary.
    \see GetMergeSummary, Merge

    \return true if the merge was OK'ed by the user, false otherwise
 */
bool ShowMergeSummary(wxWindow *parent, ProgressInfo *progress, CatalogPtr po, CatalogPtr refcat, bool *cancelledByUser)
{
    if (cancelledByUser)
        *cancelledByUser = false;
    if (wxConfig::Get()->ReadBool("show_summary", false))
    {
        wxArrayString snew, sobsolete;
        GetMergeSummary(po, refcat, snew, sobsolete);
        MergeSummaryDialog sdlg(parent);
        sdlg.TransferTo(snew, sobsolete);

        if (progress)
            progress->Hide();
        bool ok = (sdlg.ShowModal() == wxID_OK);
        if (progress)
            progress->Show();

        if (cancelledByUser)
            *cancelledByUser = !ok;
        return ok;
    }
    else
        return true;
}

} // anonymous namespace

bool PerformUpdateFromSources(wxWindow *parent,
                              CatalogPtr catalog,
                              UpdateResultReason& reason,
                              int flags)
{
    const bool skipSummary = (flags & Update_DontShowSummary);

    ProgressInfo progress(parent, _("Updating catalog"));

    reason = UpdateResultReason::Unspecified;
    if (!catalog->IsOk())
        return false;

    auto spec = catalog->GetSourceCodeSpec();
    if (!spec)
    {
        reason = UpdateResultReason::NoSourcesFound;
        return false;
    }

    CatalogPtr pot = nullptr;

    progress.PulseGauge();
    progress.UpdateMessage(_("Collecting source files..."));

    auto files = Extractor::CollectAllFiles(*spec);

    progress.PulseGauge();
    progress.UpdateMessage(_("Extracting translatable strings..."));

    if (!files.empty())
    {
        TempDirectory tmpdir;
        auto potFile = Extractor::ExtractWithAll(tmpdir, *spec, files);
        if (!potFile.empty())
        {
            pot = std::make_shared<Catalog>(potFile, Catalog::CreationFlag_IgnoreHeader);
            if (!pot->IsOk())
            {
                wxLogError(_("Failed to load extracted catalog."));
                pot.reset();
            }
        }
    }
    else
    {
        reason = UpdateResultReason::NoSourcesFound;
    }

    if (progress.Cancelled())
    {
        reason = UpdateResultReason::CancelledByUser;
        return false;
    }

    if (!pot)
        return false;

    progress.UpdateMessage(_("Merging differences..."));

    bool succ = false;
    bool cancelledByUser = false;
    if (skipSummary || ShowMergeSummary(parent, &progress, catalog, pot, &cancelledByUser))
    {
        succ = catalog->UpdateFromPOT(pot);
    }

    if (cancelledByUser)
        reason = UpdateResultReason::CancelledByUser;

    return succ;
}

bool PerformUpdateFromPOT(wxWindow *parent,
                          CatalogPtr catalog,
                          const wxString& pot_file,
                          UpdateResultReason& reason)
{
    reason = UpdateResultReason::Unspecified;
    if (!catalog->IsOk())
        return false;

    CatalogPtr pot = std::make_shared<Catalog>(pot_file, Catalog::CreationFlag_IgnoreTranslations);

    if (!pot->IsOk())
    {
        wxLogError(_("'%s' is not a valid POT file."), pot_file.c_str());
        return false;
    }

    bool cancelledByUser = false;
    if (ShowMergeSummary(parent, nullptr, catalog, pot, &cancelledByUser))
    {
        return catalog->UpdateFromPOT(pot);
    }
    else
    {
        if (cancelledByUser)
            reason = UpdateResultReason::CancelledByUser;
        return false;
    }
}
<|endoftext|>


<commit_before>#include "Scripting.h"
#include "Log.h"
#include "platform.h"
#include "utils/FileSystemUtil.h"

namespace Scripting
{
    int fireEvent(const std::string& eventName, const std::string& arg1, const std::string& arg2)
    {
        LOG(LogDebug) << "fireEvent: " << eventName << " " << arg1 << " " << arg2;

        std::list<std::string> scriptDirList;
        std::string test;

        // check in exepath
        test = Utils::FileSystem::getExePath() + "/scripts/" + eventName;
        if(Utils::FileSystem::exists(test))
            scriptDirList.push_back(test);

        // check in homepath
        test = Utils::FileSystem::getHomePath() + "/.emulationstation/scripts/" + eventName;
        if(Utils::FileSystem::exists(test))
            scriptDirList.push_back(test);
        // loop over found script paths per event and over scripts found in eventName folder.
        for(std::list<std::string>::const_iterator dirIt = scriptDirList.cbegin(); dirIt != scriptDirList.cend(); ++dirIt) {
            std::list<std::string> scripts = Utils::FileSystem::getDirContent(*dirIt);
            for (std::list<std::string>::const_iterator it = scripts.cbegin(); it != scripts.cend(); ++it) {
#ifndef WIN32 // osx / linux
                if (!Utils::FileSystem::isExecutable(*it)) {
                    LOG(LogWarning) << *it << " is not executable. Did you 'chmod u+x'?. Skipping this script.";
                    continue;
                }
#endif
                std::string script = *it;
                if (arg1.length() > 0) {
                    script += " \"" + arg1 + "\"";
                    if (arg2.length() > 0) {
                        script += " \"" + arg2 + "\"";
                    }
                }
                LOG(LogDebug) << "  executing: " << script;
                return runSystemCommand(script);
            }
        }
    }

} // Scripting::
<commit_msg>Fix to terminate execution of scripts if current script fails.<commit_after>#include "Scripting.h"
#include "Log.h"
#include "platform.h"
#include "utils/FileSystemUtil.h"

namespace Scripting
{
    int fireEvent(const std::string& eventName, const std::string& arg1, const std::string& arg2)
    {
        LOG(LogDebug) << "fireEvent: " << eventName << " " << arg1 << " " << arg2;

        std::list<std::string> scriptDirList;
        std::string test;

        // check in exepath
        test = Utils::FileSystem::getExePath() + "/scripts/" + eventName;
        if(Utils::FileSystem::exists(test))
            scriptDirList.push_back(test);

        // check in homepath
        test = Utils::FileSystem::getHomePath() + "/.emulationstation/scripts/" + eventName;
        if(Utils::FileSystem::exists(test))
            scriptDirList.push_back(test);
        int ret = 0;
        // loop over found script paths per event and over scripts found in eventName folder.
        for(std::list<std::string>::const_iterator dirIt = scriptDirList.cbegin(); dirIt != scriptDirList.cend(); ++dirIt) {
            std::list<std::string> scripts = Utils::FileSystem::getDirContent(*dirIt);
            for (std::list<std::string>::const_iterator it = scripts.cbegin(); it != scripts.cend(); ++it) {
#ifndef WIN32 // osx / linux
                if (!Utils::FileSystem::isExecutable(*it)) {
                    LOG(LogWarning) << *it << " is not executable. Did you 'chmod u+x'?. Skipping this script.";
                    continue;
                }
#endif
                std::string script = *it;
                if (arg1.length() > 0) {
                    script += " \"" + arg1 + "\"";
                    if (arg2.length() > 0) {
                        script += " \"" + arg2 + "\"";
                    }
                }
                LOG(LogDebug) << "executing: " << script;
                ret = runSystemCommand(script);
                if (ret != 0) {
                    LOG(LogWarning) << script << " failed with rc != 0. Skipping further processing of scripts.";
                    return ret;
                }
            }
        }
        return ret;
    }

} // Scripting::
<|endoftext|>


<commit_before>#ifndef MAKE_UNIQUE_HPP
#define MAKE_UNIQUE_HPP

#include <memory>

#include "namespace_utils.hpp"

BEGIN_NAMESPACE_ETL

BEGIN_NAMESPACE_UTILS

template <typename T, typename... Args> std::unique_ptr<T> make_unique(Args&&... args)
{
	return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

END_NAMESPACE_UTILS

END_NAMESPACE_ETL

#endif // MAKE_UNIQUE_HPP
<commit_msg>small correction<commit_after>#ifndef MAKE_UNIQUE_HPP
#define MAKE_UNIQUE_HPP

#include <memory>

#include "namespace_utils.hpp"

BEGIN_NAMESPACE_ETL

BEGIN_NAMESPACE_UTILS

template<class T, class ... Args> std::unique_ptr<T> make_unique(Args&&... args)
{
	return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

END_NAMESPACE_UTILS

END_NAMESPACE_ETL

#endif // MAKE_UNIQUE_HPP
<|endoftext|>


<commit_before>#include "clustering.hpp"

#include "constant_series.hpp"
#include "monomials.hpp"
#include "nchoosek.hpp"
#include "p_max_total.hpp"

namespace fgt {

namespace {

double ddist(const arma::rowvec& x, const arma::rowvec& y) {
    return arma::accu(arma::pow(x - y, 2));
}
}

Clustering::Clustering(const arma::mat& source, arma::uword K, double bandwidth,
                       double epsilon)
    : m_source(source),
      m_K(K),
      m_indices(arma::zeros<arma::uvec>(source.n_rows)),
      m_centers(arma::zeros<arma::mat>(K, source.n_cols)),
      m_num_points(arma::zeros<arma::uvec>(K)),
      m_radii(K),
      m_rx(),
      m_bandwidth(bandwidth),
      m_epsilon(epsilon),
      m_p_max(0),
      m_constant_series() {}

Clustering::~Clustering() {}

arma::uword Clustering::choose_truncation_number(int dimensions,
                                                 double bandwidth,
                                                 double epsilon, double rx) {
    double r = std::min(std::sqrt(dimensions),
                        bandwidth * std::sqrt(std::log(1 / epsilon)));
    double rx2 = rx * rx;
    double h2 = bandwidth * bandwidth;
    double error = 1;
    double temp = 1;
    int p = 0;

    while ((error > epsilon) and (p <= TruncationNumberUpperLimit)) {
        ++p;
        double b = std::min((rx + std::sqrt(rx2 + 2 * p * h2)) / 2, rx + r);
        double c = rx - b;
        temp *= 2 * rx * b / h2 / p;
        error = temp * std::exp(-c * c / h2);
    }

    return p;
}

void Clustering::cluster() {
    cluster_impl();
    m_p_max =
        choose_truncation_number(m_source.n_cols, m_bandwidth, m_epsilon, m_rx);
    m_constant_series = compute_constant_series(m_source.n_cols, m_p_max);
}

arma::mat Clustering::compute_C(const arma::vec& q) const {
    arma::mat C = arma::zeros<arma::mat>(
        m_centers.n_rows, get_p_max_total(m_source.n_cols, m_p_max));
    std::vector<double> monomials(C.n_cols);
    double h2 = m_bandwidth * m_bandwidth;

    for (arma::uword i = 0; i < m_source.n_rows; ++i) {
        arma::uword k = m_indices(i);
        arma::rowvec dx = m_source.row(i) - m_centers.row(k);
        double distance2 = arma::accu(arma::pow(dx, 2));
        compute_monomials(dx / m_bandwidth, m_p_max, monomials);
        double f = q(i) * std::exp(-distance2 / h2);
        // TODO remove rowvec
        arma::rowvec center_monomials(monomials);
        C.row(k) += f * center_monomials;
    }

    arma::rowvec constant_series =
        compute_constant_series(m_source.n_cols, m_p_max);
    for (arma::uword i = 0; i < C.n_rows; ++i) {
        C.row(i) = C.row(i) % constant_series;
    }

    return C;
}

const optional_arma_uword_t GonzalezClustering::DefaultStartingIndex = {false,
                                                                        0};

GonzalezClustering::GonzalezClustering(const arma::mat& source, int K,
                                       double bandwidth, double epsilon,
                                       optional_arma_uword_t starting_index)
    : Clustering(source, K, bandwidth, epsilon),
      m_starting_index(starting_index) {}

void GonzalezClustering::cluster_impl() {
    arma::uword N = get_n_rows();
    arma::uword K = get_K();
    arma::uvec centers(K);
    arma::uvec cprev(N);
    arma::uvec cnext(N);
    arma::uvec far2c(K);
    arma::vec dist(N);

    arma::uword nc;
    if (m_starting_index.first) {
        nc = m_starting_index.second;
    } else {
        std::random_device rd;
        nc = rd() % N;
    }
    centers(0) = nc;

    for (arma::uword i = 0; i < N; ++i) {
        dist(i) =
            (i == nc) ? 0.0 : ddist(get_source_row(i), get_source_row(nc));
        cnext(i) = i + 1;
        cprev(i) = i - 1;
    }

    cnext(N - 1) = 0;
    cprev(0) = N - 1;

    nc = std::max_element(dist.begin(), dist.end()) - dist.begin();
    far2c(0) = nc;
    set_radius(0, dist(nc));

    for (int i = 1; i < K; ++i) {
        nc = far2c(get_radius_idxmax(i));

        centers(i) = nc;
        set_radius(i, 0.0);
        dist(nc) = 0.0;
        set_index(nc, i);
        far2c(i) = nc;

        cnext(cprev(nc)) = cnext(nc);
        cprev(cnext(nc)) = cprev(nc);
        cnext(nc) = nc;
        cprev(nc) = nc;

        for (int j = 0; j < i; ++j) {
            arma::uword ct_j = centers(j);
            double dc2cq = ddist(get_source_row(ct_j), get_source_row(nc)) / 4;
            if (dc2cq < get_radius(j)) {
                set_radius(j, 0.0);
                far2c(j) = ct_j;
                arma::uword k = cnext(ct_j);
                while (k != ct_j) {
                    arma::uword nextk = cnext(k);
                    double dist2c_k = dist(k);
                    if (dc2cq < dist2c_k) {
                        double dd =
                            ddist(get_source_row(k), get_source_row(nc));
                        if (dd < dist2c_k) {
                            dist(k) = dd;
                            set_index(k, i);
                            if (get_radius(i) < dd) {
                                set_radius(i, dd);
                                far2c(i) = k;
                            }
                            cnext(cprev(k)) = nextk;
                            cprev(nextk) = cprev(k);
                            cnext(k) = cnext(nc);
                            cprev(cnext(nc)) = k;
                            cnext(nc) = k;
                            cprev(k) = nc;
                        } else if (get_radius(j) < dist2c_k) {
                            set_radius(j, dist2c_k);
                            far2c(j) = k;
                        }
                    } else if (get_radius(j) < dist2c_k) {
                        set_radius(j, dist2c_k);
                        far2c(j) = k;
                    }
                    k = nextk;
                }
            }
        }
    }

    set_radii(arma::sqrt(get_radii()));
    set_rx(get_max_radius());

    arma::mat center_coordinates(get_centers());
    for (arma::uword i = 0; i < N; ++i) {
        increment_num_points(get_index(i));
        center_coordinates.row(get_index(i)) += get_source_row(i);
    }
    set_centers(center_coordinates /
                arma::repmat(get_num_points(), 1, get_d()));
}
}
<commit_msg>Don't allocate a new arma rowvec every monomial<commit_after>#include "clustering.hpp"

#include "constant_series.hpp"
#include "monomials.hpp"
#include "nchoosek.hpp"
#include "p_max_total.hpp"

namespace fgt {

namespace {

double ddist(const arma::rowvec& x, const arma::rowvec& y) {
    return arma::accu(arma::pow(x - y, 2));
}
}

Clustering::Clustering(const arma::mat& source, arma::uword K, double bandwidth,
                       double epsilon)
    : m_source(source),
      m_K(K),
      m_indices(arma::zeros<arma::uvec>(source.n_rows)),
      m_centers(arma::zeros<arma::mat>(K, source.n_cols)),
      m_num_points(arma::zeros<arma::uvec>(K)),
      m_radii(K),
      m_rx(),
      m_bandwidth(bandwidth),
      m_epsilon(epsilon),
      m_p_max(0),
      m_constant_series() {}

Clustering::~Clustering() {}

arma::uword Clustering::choose_truncation_number(int dimensions,
                                                 double bandwidth,
                                                 double epsilon, double rx) {
    double r = std::min(std::sqrt(dimensions),
                        bandwidth * std::sqrt(std::log(1 / epsilon)));
    double rx2 = rx * rx;
    double h2 = bandwidth * bandwidth;
    double error = 1;
    double temp = 1;
    int p = 0;

    while ((error > epsilon) and (p <= TruncationNumberUpperLimit)) {
        ++p;
        double b = std::min((rx + std::sqrt(rx2 + 2 * p * h2)) / 2, rx + r);
        double c = rx - b;
        temp *= 2 * rx * b / h2 / p;
        error = temp * std::exp(-c * c / h2);
    }

    return p;
}

void Clustering::cluster() {
    cluster_impl();
    m_p_max =
        choose_truncation_number(m_source.n_cols, m_bandwidth, m_epsilon, m_rx);
    m_constant_series = compute_constant_series(m_source.n_cols, m_p_max);
}

arma::mat Clustering::compute_C(const arma::vec& q) const {
    arma::mat C = arma::zeros<arma::mat>(
        m_centers.n_rows, get_p_max_total(m_source.n_cols, m_p_max));
    std::vector<double> monomials(C.n_cols);
    double h2 = m_bandwidth * m_bandwidth;

    for (arma::uword i = 0; i < m_source.n_rows; ++i) {
        arma::uword k = m_indices(i);
        arma::rowvec dx = m_source.row(i) - m_centers.row(k);
        double distance2 = arma::accu(arma::pow(dx, 2));
        compute_monomials(dx / m_bandwidth, m_p_max, monomials);
        double f = q(i) * std::exp(-distance2 / h2);
        for (arma::uword j = 0; j < monomials.size(); ++j) {
            C(k, j) += f * monomials[j];
        }
    }

    arma::rowvec constant_series =
        compute_constant_series(m_source.n_cols, m_p_max);
    for (arma::uword i = 0; i < C.n_rows; ++i) {
        C.row(i) = C.row(i) % constant_series;
    }

    return C;
}

const optional_arma_uword_t GonzalezClustering::DefaultStartingIndex = {false,
                                                                        0};

GonzalezClustering::GonzalezClustering(const arma::mat& source, int K,
                                       double bandwidth, double epsilon,
                                       optional_arma_uword_t starting_index)
    : Clustering(source, K, bandwidth, epsilon),
      m_starting_index(starting_index) {}

void GonzalezClustering::cluster_impl() {
    arma::uword N = get_n_rows();
    arma::uword K = get_K();
    arma::uvec centers(K);
    arma::uvec cprev(N);
    arma::uvec cnext(N);
    arma::uvec far2c(K);
    arma::vec dist(N);

    arma::uword nc;
    if (m_starting_index.first) {
        nc = m_starting_index.second;
    } else {
        std::random_device rd;
        nc = rd() % N;
    }
    centers(0) = nc;

    for (arma::uword i = 0; i < N; ++i) {
        dist(i) =
            (i == nc) ? 0.0 : ddist(get_source_row(i), get_source_row(nc));
        cnext(i) = i + 1;
        cprev(i) = i - 1;
    }

    cnext(N - 1) = 0;
    cprev(0) = N - 1;

    nc = std::max_element(dist.begin(), dist.end()) - dist.begin();
    far2c(0) = nc;
    set_radius(0, dist(nc));

    for (int i = 1; i < K; ++i) {
        nc = far2c(get_radius_idxmax(i));

        centers(i) = nc;
        set_radius(i, 0.0);
        dist(nc) = 0.0;
        set_index(nc, i);
        far2c(i) = nc;

        cnext(cprev(nc)) = cnext(nc);
        cprev(cnext(nc)) = cprev(nc);
        cnext(nc) = nc;
        cprev(nc) = nc;

        for (int j = 0; j < i; ++j) {
            arma::uword ct_j = centers(j);
            double dc2cq = ddist(get_source_row(ct_j), get_source_row(nc)) / 4;
            if (dc2cq < get_radius(j)) {
                set_radius(j, 0.0);
                far2c(j) = ct_j;
                arma::uword k = cnext(ct_j);
                while (k != ct_j) {
                    arma::uword nextk = cnext(k);
                    double dist2c_k = dist(k);
                    if (dc2cq < dist2c_k) {
                        double dd =
                            ddist(get_source_row(k), get_source_row(nc));
                        if (dd < dist2c_k) {
                            dist(k) = dd;
                            set_index(k, i);
                            if (get_radius(i) < dd) {
                                set_radius(i, dd);
                                far2c(i) = k;
                            }
                            cnext(cprev(k)) = nextk;
                            cprev(nextk) = cprev(k);
                            cnext(k) = cnext(nc);
                            cprev(cnext(nc)) = k;
                            cnext(nc) = k;
                            cprev(k) = nc;
                        } else if (get_radius(j) < dist2c_k) {
                            set_radius(j, dist2c_k);
                            far2c(j) = k;
                        }
                    } else if (get_radius(j) < dist2c_k) {
                        set_radius(j, dist2c_k);
                        far2c(j) = k;
                    }
                    k = nextk;
                }
            }
        }
    }

    set_radii(arma::sqrt(get_radii()));
    set_rx(get_max_radius());

    arma::mat center_coordinates(get_centers());
    for (arma::uword i = 0; i < N; ++i) {
        increment_num_points(get_index(i));
        center_coordinates.row(get_index(i)) += get_source_row(i);
    }
    set_centers(center_coordinates /
                arma::repmat(get_num_points(), 1, get_d()));
}
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/fileutil.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-fts/QueryAnalyzer.h"
#include "fnord-fts/GermanStemmer.h"
#include "common.h"

using namespace fnord;

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  fnord::cli::FlagParser flags;

  flags.defineFlag(
      "lang",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "language",
      "<lang>");

  flags.defineFlag(
      "stopwords",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "stopwords",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  auto lang = languageFromString(flags.getString("lang"));

  fts::StopwordDictionary stopwords;
  if (flags.isSet("stopwords")) {
    stopwords.loadStopwordFile(flags.getString("stopwords"));
  } else {
    fnord::logWarning("cm-tokenize", "no stopword file provided");
  }

  fnord::fts::SynonymDictionary synonyms;
  synonyms.addSynonym(Language::DE, "mützen", "mütze");
  synonyms.addSynonym(Language::DE, "bänder", "band");

  fnord::fts::GermanStemmer german_stemmer(
      "conf/hunspell_de.aff",
      "conf/hunspell_de.dic",
      "conf/hunspell_de.hyphen",
      &synonyms);

  fts::QueryAnalyzer analyzer(&stopwords, &german_stemmer);
  for (String line; std::getline(std::cin, line); ) {
    Set<String> tokens;
    analyzer.analyze(lang, line, &tokens);
    fnord::iputs("\ninput: $0\noutput: $1", line, tokens);
  }

  return 0;
}

<commit_msg>ignore utf8 dingbats in tokenization<commit_after>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/fileutil.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-fts/QueryAnalyzer.h"
#include "fnord-fts/GermanStemmer.h"
#include "common.h"

using namespace fnord;

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  fnord::cli::FlagParser flags;

  flags.defineFlag(
      "lang",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "language",
      "<lang>");

  flags.defineFlag(
      "stopwords",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "stopwords",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  auto lang = languageFromString(flags.getString("lang"));

  fts::StopwordDictionary stopwords;
  if (flags.isSet("stopwords")) {
    stopwords.loadStopwordFile(flags.getString("stopwords"));
  } else {
    fnord::logWarning("cm-tokenize", "no stopword file provided");
  }

  fnord::fts::SynonymDictionary synonyms;
  synonyms.addSynonym(Language::DE, "mützen", "mütze");
  synonyms.addSynonym(Language::DE, "bänder", "band");
  synonyms.addSynonym(Language::DE, "girlanden", "girlande");

  fnord::fts::GermanStemmer german_stemmer(
      "conf/hunspell_de.aff",
      "conf/hunspell_de.dic",
      "conf/hunspell_de.hyphen",
      &synonyms);

  fts::QueryAnalyzer analyzer(&stopwords, &german_stemmer);
  for (String line; std::getline(std::cin, line); ) {
    Set<String> tokens;
    analyzer.analyze(lang, line, &tokens);
    fnord::iputs("\ninput: $0\noutput: $1", line, tokens);
  }

  return 0;
}

<|endoftext|>


<commit_before>#ifndef DISTRIBUTION_HPP
#define DISTRIBUTION_HPP

#include <random>

class Distribution {
public:
    virtual unsigned int nextTimeDelta (std::default_random_engine rng) = 0;
};

class Geometric : public Distribution{
public:
    Geometric(std::string params) {

        p_ = std::stod(params);
        if (p_ <= 0 || p_ >= 1) {
            std::cerr << "Geometric Distribution: Invalid parameter." << std::endl;
            abort();
        }
    }

    unsigned int nextTimeDelta(std::default_random_engine rng) {

        std::geometric_distribution<int> distribution(p_);
        return (unsigned int)std::max(distribution(rng), 1);
    }

private:
    double p_ = 0.0;
};

class Exponential : public Distribution{
public:
    Exponential(std::string params) {

        lambda_ = std::stod(params);
        if (!lambda_) {
            std::cerr << "Exponential Distribution: Invalid parameter." << std::endl;
            abort();
        }
    }

    unsigned int nextTimeDelta(std::default_random_engine rng) {
        std::exponential_distribution<double> distribution(lambda_);
        return (unsigned int)std::max(distribution(rng), 1.0);
    }

private:
    double lambda_ = 0.0;
};

class Binomial : public Distribution {
public:
    Binomial (std::string params) {

        std::string delimiter = ",";
        size_t pos = params.find(delimiter);
        t_ = (unsigned int) std::stoul(params.substr(0,pos));
        p_ = std::stod(params.substr(pos+1));
        if (p_ <= 0 || p_ >= 1) {
            std::cerr << "Binomial Distribution: Invalid parameter." << std::endl;
            abort();
        }
    }

    unsigned int nextTimeDelta(std::default_random_engine rng) {

        std::binomial_distribution<int> distribution(t_, p_);
        return (unsigned int)std::max(distribution(rng), 1);
    }

private:
    unsigned int t_ = 0.0;
    double p_ = 0.0;
};

class Cauchy : public Distribution {
public:
    Cauchy (std::string params) {

        std::string delimiter = ",";
        size_t pos = params.find(delimiter);
        a_ = std::stod(params.substr(0,pos));
        b_ = std::stod(params.substr(pos+1));
        if (!a_ || !b_) {
            std::cerr << "Cauchy Distribution: Invalid parameter." << std::endl;
            abort();
        }
    }

    unsigned int nextTimeDelta(std::default_random_engine rng) {

        std::cauchy_distribution<double> distribution(a_, b_);
        return (unsigned int)std::max(distribution(rng), 1.0);
    }

private:
    double a_ = 0.0, b_ = 0.0;
};

class Chi_squared : public Distribution {
public:
    Chi_squared (std::string params) {

        n_ = std::stod(params);
        if (!n_) {
            std::cerr << "Chi squared Distribution: Invalid parameter." << std::endl;
            abort();
        }
    }

    unsigned int nextTimeDelta(std::default_random_engine rng) {

        std::chi_squared_distribution<double> distribution(n_);
        return (unsigned int)std::max(distribution(rng), 1.0);
    }

private:
    double n_ = 0.0;
};

class Discrete : public Distribution {
public:
    Discrete (std::string params) {

        std::string delimiter = ",";
        size_t pos = params.find(delimiter);
        first_ = std::stod(params.substr(0,pos));
        last_ = std::stod(params.substr(pos+1));
        if (!first_ || !last_) {
            std::cerr << "Discrete Distribution: Invalid parameter." << std::endl;
            abort();
        }
    }

    unsigned int nextTimeDelta(std::default_random_engine rng) {

        std::discrete_distribution<int> distribution(first_, last_);
        return (unsigned int)std::max(distribution(rng), 1);
    }

private:
    double first_ = 0.0, last_ = 0.0;
};

#endif
<commit_msg>added new distribution<commit_after>#ifndef DISTRIBUTION_HPP
#define DISTRIBUTION_HPP

#include <random>

class Distribution {
public:
    virtual unsigned int nextTimeDelta (std::default_random_engine rng) = 0;
};

class Geometric : public Distribution{
public:
    Geometric(std::string params) {

        p_ = std::stod(params);
        if (p_ <= 0 || p_ >= 1) {
            std::cerr << "Geometric Distribution: Invalid parameter." << std::endl;
            abort();
        }
    }

    unsigned int nextTimeDelta(std::default_random_engine rng) {

        std::geometric_distribution<int> distribution(p_);
        return (unsigned int)std::max(distribution(rng), 1);
    }

private:
    double p_ = 0.0;
};

class Exponential : public Distribution{
public:
    Exponential(std::string params) {

        lambda_ = std::stod(params);
        if (!lambda_) {
            std::cerr << "Exponential Distribution: Invalid parameter." << std::endl;
            abort();
        }
    }

    unsigned int nextTimeDelta(std::default_random_engine rng) {
        std::exponential_distribution<double> distribution(lambda_);
        return (unsigned int)std::max(distribution(rng), 1.0);
    }

private:
    double lambda_ = 0.0;
};

class Binomial : public Distribution {
public:
    Binomial (std::string params) {

        std::string delimiter = ",";
        size_t pos = params.find(delimiter);
        t_ = (unsigned int) std::stoul(params.substr(0,pos));
        p_ = std::stod(params.substr(pos+1));
        if (p_ <= 0 || p_ >= 1) {
            std::cerr << "Binomial Distribution: Invalid parameter." << std::endl;
            abort();
        }
    }
/* binomial distribution returns within range of (0,t), return value + 1 to void returning 0 */
    unsigned int nextTimeDelta(std::default_random_engine rng) {

        std::binomial_distribution<int> distribution(t_, p_);
        return (unsigned int)std::max(distribution(rng), 1) + 1;
    }

private:
    unsigned int t_ = 0.0;
    double p_ = 0.0;
};

class Cauchy : public Distribution {
public:
    Cauchy (std::string params) {

        std::string delimiter = ",";
        size_t pos = params.find(delimiter);
        a_ = std::stod(params.substr(0,pos));
        b_ = std::stod(params.substr(pos+1));
        if (!a_ || !b_) {
            std::cerr << "Cauchy Distribution: Invalid parameter." << std::endl;
            abort();
        }
    }

    unsigned int nextTimeDelta(std::default_random_engine rng) {

        std::cauchy_distribution<double> distribution(a_, b_);
        return (unsigned int)std::max(distribution(rng), 1.0);
    }

private:
    double a_ = 0.0, b_ = 0.0;
};

class Chi_squared : public Distribution {
public:
    Chi_squared (std::string params) {

        n_ = std::stod(params);
        if (!n_) {
            std::cerr << "Chi Squared Distribution: Invalid parameter." << std::endl;
            abort();
        }
    }

    unsigned int nextTimeDelta(std::default_random_engine rng) {

        std::chi_squared_distribution<double> distribution(n_);
        return (unsigned int)std::max(distribution(rng), 1.0);
    }

private:
    double n_ = 0.0;
};

class Discrete : public Distribution {
public:
    Discrete (std::string params) {

        std::string delimiter = ",";
        size_t pos = params.find(delimiter);
        first_ = std::stod(params.substr(0,pos));
        last_ = std::stod(params.substr(pos+1));
        if (!first_ || !last_) {
            std::cerr << "Discrete Distribution: Invalid parameter." << std::endl;
            abort();
        }
    }

    unsigned int nextTimeDelta(std::default_random_engine rng) {

        std::discrete_distribution<int> distribution(first_, last_);
        return (unsigned int)std::max(distribution(rng), 1);
    }

private:
    double first_ = 0.0, last_ = 0.0;
};

class Fisher_f : public Distribution {
public:
    Fisher_f (std::string params) {

        std::string delimiter = ",";
        size_t pos = params.find(delimiter);
        m_ = std::stod(params.substr(0,pos));
        n_ = std::stod(params.substr(pos+1));
        if (!m_ || !n_) {
            std::cerr << "Fisher F Distribution: Invalid parameter." << std::endl;
            abort();
        }
    }

    unsigned int nextTimeDelta(std::default_random_engine rng) {

        std::fisher_f_distribution<double> distribution (m_, n_);
        return (unsigned int)std::max(distribution(rng), 1.0);
    }

private:
    double m_ = 0.0, n_ = 0.0;
};

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2003 Daniel Wallin and Arvid Norberg

// 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.

#define LUABIND_BUILDING

#include <luabind/lua_include.hpp>

#include <luabind/luabind.hpp>
#include <luabind/class_info.hpp>
#include <luabind/detail/class_registry.hpp>
#include <luabind/lua_argument_proxy.hpp>
#include <luabind/lua_iterator_proxy.hpp>
#include <___unused.h>

/*
#include <iostream>
#define VERBOSE(X) std::cout << __FILE__ << ":" << __LINE__ << ": " << X << std::endl
*/
#define VERBOSE(X)

namespace luabind
{
	LUABIND_API class_info get_class_info(argument const& o)
	{
		lua_State* L = o.interpreter();
        detail::class_rep * crep = NULL;

        _unused(givenClassRep);

		o.push(L);
		if (detail::is_class_rep(L, -1)) {
			VERBOSE("OK, got a class rep");
            // OK, o is a class rep, now at the top of the stack
			crep = static_cast<detail::class_rep *>(lua_touserdata(L, -1));
			lua_pop(L, 1);
		} else {

			VERBOSE("Not a class rep");
			detail::object_rep* obj = detail::get_instance(L, -1);

			if (!obj)
			{
				VERBOSE("Not a obj rep");
			    class_info result;
			    result.name = lua_typename(L, lua_type(L, -1));
			    lua_pop(L, 1);
			    result.methods = newtable(L);
			    result.attributes = newtable(L);
			    return result;
			} else {
		        lua_pop(L, 1);
				// OK, we were given an object - gotta get the crep.
				crep = obj->crep();
			}
		}
		crep->get_table(L);
        object table(from_stack(L, -1));
        lua_pop(L, 1);

        class_info result;
        result.name = crep->name();
        result.methods = newtable(L);
        result.attributes = newtable(L);

        std::size_t index = 1;

        for (iterator i(table), e; i != e; ++i)
        {
            if (type(*i) != LUA_TFUNCTION)
                continue;

            // We have to create a temporary `object` here, otherwise the proxy
            // returned by operator->() will mess up the stack. This is a known
            // problem that probably doesn't show up in real code very often.
            object member(*i);
            member.push(L);
            detail::stack_pop pop(L, 1);

            if (lua_tocfunction(L, -1) == &detail::property_tag)
            {
                result.attributes[index++] = i.key();
            }
            else
            {
                result.methods[i.key()] = *i;
            }
        }

        return result;
	}

    LUABIND_API object get_class_names(lua_State* L)
    {
        detail::class_registry* reg = detail::class_registry::get_registry(L);

        std::map<type_id, detail::class_rep*> const& classes = reg->get_classes();

        object result = newtable(L);
        std::size_t index = 1;

        for (std::map<type_id, detail::class_rep*>::const_iterator iter = classes.begin();
            iter != classes.end(); ++iter)
        {
            result[index++] = iter->second->name();
        }

        return result;
    }

	LUABIND_API void bind_class_info(lua_State* L)
	{
		module(L)
		[
			class_<class_info>("class_info_data")
				.def_readonly("name", &class_info::name)
				.def_readonly("methods", &class_info::methods)
				.def_readonly("attributes", &class_info::attributes),

            def("class_info", &get_class_info),
            def("class_names", &get_class_names)
		];
	}
}

<commit_msg>Tiny change<commit_after>// Copyright (c) 2003 Daniel Wallin and Arvid Norberg

// 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.

#define LUABIND_BUILDING

#include <luabind/lua_include.hpp>

#include <luabind/luabind.hpp>
#include <luabind/class_info.hpp>
#include <luabind/detail/class_registry.hpp>
#include <luabind/lua_argument_proxy.hpp>
#include <luabind/lua_iterator_proxy.hpp>

/*
#include <iostream>
#define VERBOSE(X) std::cout << __FILE__ << ":" << __LINE__ << ": " << X << std::endl
*/
#define VERBOSE(X)

namespace luabind
{
	LUABIND_API class_info get_class_info(argument const& o)
	{
		lua_State* L = o.interpreter();
        detail::class_rep * crep = NULL;

		o.push(L);
		if (detail::is_class_rep(L, -1)) {
			VERBOSE("OK, got a class rep");
            // OK, o is a class rep, now at the top of the stack
			crep = static_cast<detail::class_rep *>(lua_touserdata(L, -1));
			lua_pop(L, 1);
		} else {

			VERBOSE("Not a class rep");
			detail::object_rep* obj = detail::get_instance(L, -1);

			if (!obj)
			{
				VERBOSE("Not a obj rep");
			    class_info result;
			    result.name = lua_typename(L, lua_type(L, -1));
			    lua_pop(L, 1);
			    result.methods = newtable(L);
			    result.attributes = newtable(L);
			    return result;
			} else {
		        lua_pop(L, 1);
				// OK, we were given an object - gotta get the crep.
				crep = obj->crep();
			}
		}
		crep->get_table(L);
        object table(from_stack(L, -1));
        lua_pop(L, 1);

        class_info result;
        result.name = crep->name();
        result.methods = newtable(L);
        result.attributes = newtable(L);

        std::size_t index = 1;

        for (iterator i(table), e; i != e; ++i)
        {
            if (type(*i) != LUA_TFUNCTION)
                continue;

            // We have to create a temporary `object` here, otherwise the proxy
            // returned by operator->() will mess up the stack. This is a known
            // problem that probably doesn't show up in real code very often.
            object member(*i);
            member.push(L);
            detail::stack_pop pop(L, 1);

            if (lua_tocfunction(L, -1) == &detail::property_tag)
            {
                result.attributes[index++] = i.key();
            }
            else
            {
                result.methods[i.key()] = *i;
            }
        }

        return result;
	}

    LUABIND_API object get_class_names(lua_State* L)
    {
        detail::class_registry* reg = detail::class_registry::get_registry(L);

        std::map<type_id, detail::class_rep*> const& classes = reg->get_classes();

        object result = newtable(L);
        std::size_t index = 1;

        for (std::map<type_id, detail::class_rep*>::const_iterator iter = classes.begin();
            iter != classes.end(); ++iter)
        {
            result[index++] = iter->second->name();
        }

        return result;
    }

	LUABIND_API void bind_class_info(lua_State* L)
	{
		module(L)
		[
			class_<class_info>("class_info_data")
				.def_readonly("name", &class_info::name)
				.def_readonly("methods", &class_info::methods)
				.def_readonly("attributes", &class_info::attributes),

            def("class_info", &get_class_info),
            def("class_names", &get_class_names)
		];
	}
}

<|endoftext|>