<commit_before>#include <functional>
#include <iostream>
#include <thread>

using namespace std::placeholders;

#include "../../shared/concurrency.h"
#include "../../shared/environment.h"
#include "../../shared/work_queue.h"
#include "function_pool.h"
#include "rtc_cache.h"
#include "rtc_realcomplex_gen.h"
#include "rtc_stockham_gen.h"

#include "device/kernel-generator-embed.h"

#if __has_include(<filesystem>)
#include <filesystem>
#else
#include <experimental/filesystem>
namespace std
{
    namespace filesystem = experimental::filesystem;
}
#endif
namespace fs = std::filesystem;

struct WorkItem
{
    std::string      kernel_name;
    kernel_src_gen_t generate_src;
};
typedef WorkQueue<WorkItem> CompileQueue;

// call supplied function with exploded out combinations of
// direction, placement, array types, unitstride-ness, callbacks
void stockham_combo(ComputeScheme             scheme,
                    FFTKernel                 kernel,
                    std::function<void(int,
                                       rocfft_result_placement,
                                       rocfft_array_type,
                                       rocfft_array_type,
                                       EmbeddedType,
                                       SBRC_TRANSPOSE_TYPE,
                                       DirectRegType,
                                       IntrinsicAccessType,
                                       int,
                                       int,
                                       bool,
                                       bool)> func)
{
    // unit stride is the common case, default to that
    std::vector<bool>                    unitstride_range = {true};
    std::vector<rocfft_result_placement> placements       = {rocfft_placement_notinplace};
    std::vector<EmbeddedType>            ebtypes          = {EmbeddedType::NONE};
    std::vector<SBRC_TRANSPOSE_TYPE>     sbrc_trans_types = {SBRC_TRANSPOSE_TYPE::NONE};
    std::vector<DirectRegType>           dir_reg_types    = {FORCE_OFF_OR_NOT_SUPPORT};
    std::vector<IntrinsicAccessType>     intrinsic_modes  = {DISABLE_BOTH};
    // SBCC can be used with or without large twd.  Large twd may be
    // base 4, 5, 6, 8.  Base 4 is unused since it's only useful up
    // to 4k lengths, which we already have single kernels for.  Base
    // 8 can be 2 or 3 steps; other bases are always 3 step.
    std::vector<std::array<int, 2>> base_steps = {{0, 0}, {5, 3}, {6, 3}, {8, 2}, {8, 3}};

    switch(scheme)
    {
    case CS_KERNEL_STOCKHAM_BLOCK_CC:
    {
        placements.push_back(rocfft_placement_inplace);
        // SBCC is never unit stride
        unitstride_range = {false};
        break;
    }
    case CS_KERNEL_STOCKHAM_BLOCK_CR:
    {
        base_steps.resize(1);
        // SBCR is never unit stride
        unitstride_range = {false};
        ebtypes.push_back(EmbeddedType::C2Real_PRE);
        break;
    }
    case CS_KERNEL_STOCKHAM_BLOCK_RC:
    case CS_KERNEL_STOCKHAM_TRANSPOSE_XY_Z:
    case CS_KERNEL_STOCKHAM_TRANSPOSE_Z_XY:
    case CS_KERNEL_STOCKHAM_R_TO_CMPLX_TRANSPOSE_Z_XY:
    {
        base_steps.resize(1);
        // All SBRCs have TILE_UNALIGNED
        sbrc_trans_types.push_back(SBRC_TRANSPOSE_TYPE::TILE_UNALIGNED);
        // Finish SBRC-2D
        if(scheme == CS_KERNEL_STOCKHAM_BLOCK_RC)
            break;
        // All 3D SBRCs have TILE_ALIGNED, but "NO" SBRC_TRANSPOSE_TYPE::NONE
        sbrc_trans_types.push_back(SBRC_TRANSPOSE_TYPE::TILE_ALIGNED);
        sbrc_trans_types.erase(sbrc_trans_types.begin());
        // Finish ERC
        if(scheme == CS_KERNEL_STOCKHAM_R_TO_CMPLX_TRANSPOSE_Z_XY)
            break;
        // DIAGNAL Transpose
        sbrc_trans_types.push_back(SBRC_TRANSPOSE_TYPE::DIAGONAL);
        break;
    }
    default:
        // throw std::runtime_error("unsupported scheme in stockham_combo aot_rtc");
        // since it is not possible that we are here,
        // so directly return is fine which means do nothing
        return;
    }

    // if no dir-to-reg support, then we don't have intrinsic buffer RW,
    // and only force_off_or_not_support for dir2reg. Else, we have all possibilities
    // (even force_off_or_not_support is still included)
    if(kernel.direct_to_from_reg)
    {
        dir_reg_types.push_back(TRY_ENABLE_IF_SUPPORT);
        intrinsic_modes.push_back(ENABLE_BOTH);
        intrinsic_modes.push_back(ENABLE_LOAD_ONLY);
    }

    for(auto direction : {-1, 1})
    {
        for(auto placement : placements)
        {
            for(auto inArrayType : {rocfft_array_type_complex_interleaved})
            {
                for(auto outArrayType : {rocfft_array_type_complex_interleaved})
                {
                    // inplace requires same array types
                    if(placement == rocfft_placement_inplace && inArrayType != outArrayType)
                        continue;
                    for(auto unitstride : unitstride_range)
                    {
                        for(auto base_step : base_steps)
                        {
                            for(auto ebtype : ebtypes)
                            {
                                for(auto sbrc_trans_type : sbrc_trans_types)
                                {
                                    for(auto dir_reg_type : dir_reg_types)
                                    {
                                        for(auto intrinsic : intrinsic_modes)
                                        {
                                            for(auto callback : {true, false})
                                            {
                                                func(direction,
                                                     placement,
                                                     inArrayType,
                                                     outArrayType,
                                                     ebtype,
                                                     sbrc_trans_type,
                                                     dir_reg_type,
                                                     intrinsic,
                                                     base_step[0],
                                                     base_step[1],
                                                     unitstride,
                                                     callback);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

void build_stockham_function_pool(CompileQueue& queue)
{
    // build everything in the function pool
    function_pool& fp = function_pool::get_function_pool();

    // scaling Stockham kernels are always built at runtime
    const bool enable_scaling = false;

    static const std::set<ComputeScheme> aot_rtc_supported
        = {CS_KERNEL_STOCKHAM_BLOCK_CC,
           CS_KERNEL_STOCKHAM_BLOCK_CR,
           CS_KERNEL_STOCKHAM_BLOCK_RC,
           CS_KERNEL_STOCKHAM_TRANSPOSE_XY_Z,
           CS_KERNEL_STOCKHAM_TRANSPOSE_Z_XY,
           CS_KERNEL_STOCKHAM_R_TO_CMPLX_TRANSPOSE_Z_XY};

    for(const auto& i : fp.get_map())
    {
        // we only want to compile kernels explicitly marked for AOT RTC
        if(!i.second.aot_rtc)
            continue;

        auto length1D = std::get<0>(i.first)[0];
        // auto length2D            = std::get<0>(i.first)[1];
        auto                      precision = std::get<1>(i.first);
        auto                      scheme    = std::get<2>(i.first);
        std::vector<unsigned int> factors;
        std::copy(i.second.factors.begin(), i.second.factors.end(), std::back_inserter(factors));

        if(aot_rtc_supported.count(scheme))
        {
            stockham_combo(scheme,
                           i.second,
                           [=, &queue](int                     direction,
                                       rocfft_result_placement placement,
                                       rocfft_array_type       inArrayType,
                                       rocfft_array_type       outArrayType,
                                       EmbeddedType            ebtype,
                                       SBRC_TRANSPOSE_TYPE     sbrc_trans_type,
                                       DirectRegType           dir_reg_type,
                                       IntrinsicAccessType     intrinsic,
                                       int                     ltwd_base,
                                       int                     ltwd_step,
                                       bool                    unitstride,
                                       bool                    callbacks) {
                               // intrinsic mode require non-callback and enable dir_reg
                               if((callbacks || dir_reg_type == FORCE_OFF_OR_NOT_SUPPORT)
                                  && (intrinsic != IntrinsicAccessType::DISABLE_BOTH))
                                   return;

                               auto kernel_name = stockham_rtc_kernel_name(scheme,
                                                                           length1D,
                                                                           0,
                                                                           0,
                                                                           direction,
                                                                           precision,
                                                                           placement,
                                                                           inArrayType,
                                                                           outArrayType,
                                                                           unitstride,
                                                                           ltwd_base,
                                                                           ltwd_step,
                                                                           false,
                                                                           ebtype,
                                                                           dir_reg_type,
                                                                           intrinsic,
                                                                           sbrc_trans_type,
                                                                           callbacks,
                                                                           enable_scaling);
                               std::function<std::string(const std::string&)> generate_src
                                   = [=](const std::string& kernel_name) -> std::string {
                                   StockhamGeneratorSpecs specs{
                                       factors,
                                       {},
                                       {static_cast<unsigned int>(precision)},
                                       static_cast<unsigned int>(i.second.workgroup_size),
                                       PrintScheme(scheme)};
                                   specs.threads_per_transform = i.second.threads_per_transform[0];
                                   specs.half_lds              = i.second.half_lds;
                                   specs.direct_to_from_reg    = i.second.direct_to_from_reg;
                                   return stockham_rtc(specs,
                                                       specs,
                                                       nullptr,
                                                       kernel_name,
                                                       scheme,
                                                       direction,
                                                       precision,
                                                       placement,
                                                       inArrayType,
                                                       outArrayType,
                                                       unitstride,
                                                       ltwd_base,
                                                       ltwd_step,
                                                       false,
                                                       ebtype,
                                                       dir_reg_type,
                                                       intrinsic,
                                                       sbrc_trans_type,
                                                       callbacks,
                                                       enable_scaling);
                               };
                               queue.push({kernel_name, generate_src});
                           });
        }
    }
}

void build_realcomplex(CompileQueue& queue)
{
    for(auto precision : {rocfft_precision_single, rocfft_precision_double})
    {
        for(bool planar : {true, false})
        {
            // build even-length kernels, as they're commonly used
            for(auto scheme : {CS_KERNEL_R_TO_CMPLX, CS_KERNEL_CMPLX_TO_R})
            {
                for(size_t dim : {1, 2, 3})
                {
                    for(bool Ndiv4 : {true, false})
                    {
                        // r2c may have planar output, c2r may have planar input
                        auto inArrayType  = (scheme == CS_KERNEL_CMPLX_TO_R && planar)
                                                ? rocfft_array_type_complex_planar
                                                : rocfft_array_type_complex_interleaved;
                        auto outArrayType = (scheme == CS_KERNEL_R_TO_CMPLX && planar)
                                                ? rocfft_array_type_complex_planar
                                                : rocfft_array_type_complex_interleaved;

                        RealComplexEvenSpecs specs{
                            {scheme, dim, precision, inArrayType, outArrayType, false, false},
                            Ndiv4};
                        auto kernel_name = realcomplex_even_rtc_kernel_name(specs);
                        std::function<std::string(const std::string&)> generate_src
                            = [=](const std::string& kernel_name) -> std::string {
                            return realcomplex_even_rtc(kernel_name, specs);
                        };
                        queue.push({kernel_name, generate_src});
                    }
                }
            }
            for(auto scheme : {CS_KERNEL_R_TO_CMPLX_TRANSPOSE, CS_KERNEL_TRANSPOSE_CMPLX_TO_R})
            {
                // r2c may have planar output, c2r may have planar input
                auto inArrayType  = (scheme == CS_KERNEL_TRANSPOSE_CMPLX_TO_R && planar)
                                        ? rocfft_array_type_complex_planar
                                        : rocfft_array_type_complex_interleaved;
                auto outArrayType = (scheme == CS_KERNEL_R_TO_CMPLX_TRANSPOSE && planar)
                                        ? rocfft_array_type_complex_planar
                                        : rocfft_array_type_complex_interleaved;

                RealComplexEvenTransposeSpecs specs{{scheme,
                                                     static_cast<size_t>(1),
                                                     precision,
                                                     inArrayType,
                                                     outArrayType,
                                                     false,
                                                     false}};
                auto kernel_name = realcomplex_even_transpose_rtc_kernel_name(specs);
                std::function<std::string(const std::string&)> generate_src
                    = [=](const std::string& kernel_name) -> std::string {
                    return realcomplex_even_transpose_rtc(kernel_name, specs);
                };
                queue.push({kernel_name, generate_src});
            }
        }
    }
}

int main(int argc, char** argv)
{
    if(argc < 5)
    {
        puts("Usage: rocfft_aot_helper temp_cachefile.db output_cachefile.db "
             "path/to/rocfft_rtc_helper gfx000 gfx001 ...");
        return 1;
    }

    std::string              temp_cache_file   = argv[1];
    std::string              output_cache_file = argv[2];
    std::string              rtc_helper        = argv[3];
    std::vector<std::string> gpu_archs;
    for(int i = 4; i < argc; ++i)
        gpu_archs.push_back(argv[i]);

    // default to using a persistent file in the temp dir if no cache
    // file was given
    if(temp_cache_file.empty())
        temp_cache_file = (fs::temp_directory_path() / "rocfft_temp_cache.db").string();

    // force RTC to use the temporary cache file
    rocfft_setenv("ROCFFT_RTC_CACHE_PATH", temp_cache_file.c_str());

    // disable system cache since we want to compile everything - use
    // an in-memory DB which will always be empty
    rocfft_setenv("ROCFFT_RTC_SYS_CACHE_PATH", ":memory:");

    // tell RTC where the compile helper is
    rocfft_setenv("ROCFFT_RTC_PROCESS_HELPER", rtc_helper.c_str());

    RTCCache::single = std::make_unique<RTCCache>();

    RTCCache::single->enable_write_mostly();

    CompileQueue queue;

    static const size_t      NUM_THREADS = rocfft_concurrency();
    std::vector<std::thread> threads;
    threads.reserve(NUM_THREADS);
    for(size_t i = 0; i < NUM_THREADS; ++i)
    {
        threads.emplace_back([&queue, &gpu_archs]() {
            while(true)
            {
                auto item = queue.pop();
                if(item.kernel_name.empty())
                    break;
                for(const auto& gpu_arch : gpu_archs)
                    cached_compile(item.kernel_name, gpu_arch, item.generate_src, generator_sum());
            }
        });
    }

    build_stockham_function_pool(queue);
    build_realcomplex(queue);

    // signal end of results with empty work items
    for(size_t i = 0; i < NUM_THREADS; ++i)
        queue.push({});
    for(size_t i = 0; i < NUM_THREADS; ++i)
        threads[i].join();

    // write the output file using what we collected in the temporary
    // cache
    RTCCache::single->write_aot_cache(output_cache_file, generator_sum());

    // try to shrink the temp cache file to 10 GiB
    try
    {
        RTCCache::single->cleanup_cache(static_cast<sqlite3_int64>(10) * 1024 * 1024 * 1024);
    }
    // the build should still succeed even if we fail to shrink the temp cache
    catch(std::exception&)
    {
        std::cerr << "warning: failed to shrink temp cache" << std::endl;
    }

    RTCCache::single.reset();

    return 0;
}
<commit_msg>Store temporary aot helper db in local directory instead of system-wide temp.<commit_after>#include <functional>
#include <iostream>
#include <thread>

using namespace std::placeholders;

#include "../../shared/concurrency.h"
#include "../../shared/environment.h"
#include "../../shared/work_queue.h"
#include "function_pool.h"
#include "rtc_cache.h"
#include "rtc_realcomplex_gen.h"
#include "rtc_stockham_gen.h"

#include "device/kernel-generator-embed.h"

#if __has_include(<filesystem>)
#include <filesystem>
#else
#include <experimental/filesystem>
namespace std
{
    namespace filesystem = experimental::filesystem;
}
#endif
namespace fs = std::filesystem;

struct WorkItem
{
    std::string      kernel_name;
    kernel_src_gen_t generate_src;
};
typedef WorkQueue<WorkItem> CompileQueue;

// call supplied function with exploded out combinations of
// direction, placement, array types, unitstride-ness, callbacks
void stockham_combo(ComputeScheme             scheme,
                    FFTKernel                 kernel,
                    std::function<void(int,
                                       rocfft_result_placement,
                                       rocfft_array_type,
                                       rocfft_array_type,
                                       EmbeddedType,
                                       SBRC_TRANSPOSE_TYPE,
                                       DirectRegType,
                                       IntrinsicAccessType,
                                       int,
                                       int,
                                       bool,
                                       bool)> func)
{
    // unit stride is the common case, default to that
    std::vector<bool>                    unitstride_range = {true};
    std::vector<rocfft_result_placement> placements       = {rocfft_placement_notinplace};
    std::vector<EmbeddedType>            ebtypes          = {EmbeddedType::NONE};
    std::vector<SBRC_TRANSPOSE_TYPE>     sbrc_trans_types = {SBRC_TRANSPOSE_TYPE::NONE};
    std::vector<DirectRegType>           dir_reg_types    = {FORCE_OFF_OR_NOT_SUPPORT};
    std::vector<IntrinsicAccessType>     intrinsic_modes  = {DISABLE_BOTH};
    // SBCC can be used with or without large twd.  Large twd may be
    // base 4, 5, 6, 8.  Base 4 is unused since it's only useful up
    // to 4k lengths, which we already have single kernels for.  Base
    // 8 can be 2 or 3 steps; other bases are always 3 step.
    std::vector<std::array<int, 2>> base_steps = {{0, 0}, {5, 3}, {6, 3}, {8, 2}, {8, 3}};

    switch(scheme)
    {
    case CS_KERNEL_STOCKHAM_BLOCK_CC:
    {
        placements.push_back(rocfft_placement_inplace);
        // SBCC is never unit stride
        unitstride_range = {false};
        break;
    }
    case CS_KERNEL_STOCKHAM_BLOCK_CR:
    {
        base_steps.resize(1);
        // SBCR is never unit stride
        unitstride_range = {false};
        ebtypes.push_back(EmbeddedType::C2Real_PRE);
        break;
    }
    case CS_KERNEL_STOCKHAM_BLOCK_RC:
    case CS_KERNEL_STOCKHAM_TRANSPOSE_XY_Z:
    case CS_KERNEL_STOCKHAM_TRANSPOSE_Z_XY:
    case CS_KERNEL_STOCKHAM_R_TO_CMPLX_TRANSPOSE_Z_XY:
    {
        base_steps.resize(1);
        // All SBRCs have TILE_UNALIGNED
        sbrc_trans_types.push_back(SBRC_TRANSPOSE_TYPE::TILE_UNALIGNED);
        // Finish SBRC-2D
        if(scheme == CS_KERNEL_STOCKHAM_BLOCK_RC)
            break;
        // All 3D SBRCs have TILE_ALIGNED, but "NO" SBRC_TRANSPOSE_TYPE::NONE
        sbrc_trans_types.push_back(SBRC_TRANSPOSE_TYPE::TILE_ALIGNED);
        sbrc_trans_types.erase(sbrc_trans_types.begin());
        // Finish ERC
        if(scheme == CS_KERNEL_STOCKHAM_R_TO_CMPLX_TRANSPOSE_Z_XY)
            break;
        // DIAGNAL Transpose
        sbrc_trans_types.push_back(SBRC_TRANSPOSE_TYPE::DIAGONAL);
        break;
    }
    default:
        // throw std::runtime_error("unsupported scheme in stockham_combo aot_rtc");
        // since it is not possible that we are here,
        // so directly return is fine which means do nothing
        return;
    }

    // if no dir-to-reg support, then we don't have intrinsic buffer RW,
    // and only force_off_or_not_support for dir2reg. Else, we have all possibilities
    // (even force_off_or_not_support is still included)
    if(kernel.direct_to_from_reg)
    {
        dir_reg_types.push_back(TRY_ENABLE_IF_SUPPORT);
        intrinsic_modes.push_back(ENABLE_BOTH);
        intrinsic_modes.push_back(ENABLE_LOAD_ONLY);
    }

    for(auto direction : {-1, 1})
    {
        for(auto placement : placements)
        {
            for(auto inArrayType : {rocfft_array_type_complex_interleaved})
            {
                for(auto outArrayType : {rocfft_array_type_complex_interleaved})
                {
                    // inplace requires same array types
                    if(placement == rocfft_placement_inplace && inArrayType != outArrayType)
                        continue;
                    for(auto unitstride : unitstride_range)
                    {
                        for(auto base_step : base_steps)
                        {
                            for(auto ebtype : ebtypes)
                            {
                                for(auto sbrc_trans_type : sbrc_trans_types)
                                {
                                    for(auto dir_reg_type : dir_reg_types)
                                    {
                                        for(auto intrinsic : intrinsic_modes)
                                        {
                                            for(auto callback : {true, false})
                                            {
                                                func(direction,
                                                     placement,
                                                     inArrayType,
                                                     outArrayType,
                                                     ebtype,
                                                     sbrc_trans_type,
                                                     dir_reg_type,
                                                     intrinsic,
                                                     base_step[0],
                                                     base_step[1],
                                                     unitstride,
                                                     callback);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

void build_stockham_function_pool(CompileQueue& queue)
{
    // build everything in the function pool
    function_pool& fp = function_pool::get_function_pool();

    // scaling Stockham kernels are always built at runtime
    const bool enable_scaling = false;

    static const std::set<ComputeScheme> aot_rtc_supported
        = {CS_KERNEL_STOCKHAM_BLOCK_CC,
           CS_KERNEL_STOCKHAM_BLOCK_CR,
           CS_KERNEL_STOCKHAM_BLOCK_RC,
           CS_KERNEL_STOCKHAM_TRANSPOSE_XY_Z,
           CS_KERNEL_STOCKHAM_TRANSPOSE_Z_XY,
           CS_KERNEL_STOCKHAM_R_TO_CMPLX_TRANSPOSE_Z_XY};

    for(const auto& i : fp.get_map())
    {
        // we only want to compile kernels explicitly marked for AOT RTC
        if(!i.second.aot_rtc)
            continue;

        auto length1D = std::get<0>(i.first)[0];
        // auto length2D            = std::get<0>(i.first)[1];
        auto                      precision = std::get<1>(i.first);
        auto                      scheme    = std::get<2>(i.first);
        std::vector<unsigned int> factors;
        std::copy(i.second.factors.begin(), i.second.factors.end(), std::back_inserter(factors));

        if(aot_rtc_supported.count(scheme))
        {
            stockham_combo(scheme,
                           i.second,
                           [=, &queue](int                     direction,
                                       rocfft_result_placement placement,
                                       rocfft_array_type       inArrayType,
                                       rocfft_array_type       outArrayType,
                                       EmbeddedType            ebtype,
                                       SBRC_TRANSPOSE_TYPE     sbrc_trans_type,
                                       DirectRegType           dir_reg_type,
                                       IntrinsicAccessType     intrinsic,
                                       int                     ltwd_base,
                                       int                     ltwd_step,
                                       bool                    unitstride,
                                       bool                    callbacks) {
                               // intrinsic mode require non-callback and enable dir_reg
                               if((callbacks || dir_reg_type == FORCE_OFF_OR_NOT_SUPPORT)
                                  && (intrinsic != IntrinsicAccessType::DISABLE_BOTH))
                                   return;

                               auto kernel_name = stockham_rtc_kernel_name(scheme,
                                                                           length1D,
                                                                           0,
                                                                           0,
                                                                           direction,
                                                                           precision,
                                                                           placement,
                                                                           inArrayType,
                                                                           outArrayType,
                                                                           unitstride,
                                                                           ltwd_base,
                                                                           ltwd_step,
                                                                           false,
                                                                           ebtype,
                                                                           dir_reg_type,
                                                                           intrinsic,
                                                                           sbrc_trans_type,
                                                                           callbacks,
                                                                           enable_scaling);
                               std::function<std::string(const std::string&)> generate_src
                                   = [=](const std::string& kernel_name) -> std::string {
                                   StockhamGeneratorSpecs specs{
                                       factors,
                                       {},
                                       {static_cast<unsigned int>(precision)},
                                       static_cast<unsigned int>(i.second.workgroup_size),
                                       PrintScheme(scheme)};
                                   specs.threads_per_transform = i.second.threads_per_transform[0];
                                   specs.half_lds              = i.second.half_lds;
                                   specs.direct_to_from_reg    = i.second.direct_to_from_reg;
                                   return stockham_rtc(specs,
                                                       specs,
                                                       nullptr,
                                                       kernel_name,
                                                       scheme,
                                                       direction,
                                                       precision,
                                                       placement,
                                                       inArrayType,
                                                       outArrayType,
                                                       unitstride,
                                                       ltwd_base,
                                                       ltwd_step,
                                                       false,
                                                       ebtype,
                                                       dir_reg_type,
                                                       intrinsic,
                                                       sbrc_trans_type,
                                                       callbacks,
                                                       enable_scaling);
                               };
                               queue.push({kernel_name, generate_src});
                           });
        }
    }
}

void build_realcomplex(CompileQueue& queue)
{
    for(auto precision : {rocfft_precision_single, rocfft_precision_double})
    {
        for(bool planar : {true, false})
        {
            // build even-length kernels, as they're commonly used
            for(auto scheme : {CS_KERNEL_R_TO_CMPLX, CS_KERNEL_CMPLX_TO_R})
            {
                for(size_t dim : {1, 2, 3})
                {
                    for(bool Ndiv4 : {true, false})
                    {
                        // r2c may have planar output, c2r may have planar input
                        auto inArrayType  = (scheme == CS_KERNEL_CMPLX_TO_R && planar)
                                                ? rocfft_array_type_complex_planar
                                                : rocfft_array_type_complex_interleaved;
                        auto outArrayType = (scheme == CS_KERNEL_R_TO_CMPLX && planar)
                                                ? rocfft_array_type_complex_planar
                                                : rocfft_array_type_complex_interleaved;

                        RealComplexEvenSpecs specs{
                            {scheme, dim, precision, inArrayType, outArrayType, false, false},
                            Ndiv4};
                        auto kernel_name = realcomplex_even_rtc_kernel_name(specs);
                        std::function<std::string(const std::string&)> generate_src
                            = [=](const std::string& kernel_name) -> std::string {
                            return realcomplex_even_rtc(kernel_name, specs);
                        };
                        queue.push({kernel_name, generate_src});
                    }
                }
            }
            for(auto scheme : {CS_KERNEL_R_TO_CMPLX_TRANSPOSE, CS_KERNEL_TRANSPOSE_CMPLX_TO_R})
            {
                // r2c may have planar output, c2r may have planar input
                auto inArrayType  = (scheme == CS_KERNEL_TRANSPOSE_CMPLX_TO_R && planar)
                                        ? rocfft_array_type_complex_planar
                                        : rocfft_array_type_complex_interleaved;
                auto outArrayType = (scheme == CS_KERNEL_R_TO_CMPLX_TRANSPOSE && planar)
                                        ? rocfft_array_type_complex_planar
                                        : rocfft_array_type_complex_interleaved;

                RealComplexEvenTransposeSpecs specs{{scheme,
                                                     static_cast<size_t>(1),
                                                     precision,
                                                     inArrayType,
                                                     outArrayType,
                                                     false,
                                                     false}};
                auto kernel_name = realcomplex_even_transpose_rtc_kernel_name(specs);
                std::function<std::string(const std::string&)> generate_src
                    = [=](const std::string& kernel_name) -> std::string {
                    return realcomplex_even_transpose_rtc(kernel_name, specs);
                };
                queue.push({kernel_name, generate_src});
            }
        }
    }
}

int main(int argc, char** argv)
{
    if(argc < 5)
    {
        puts("Usage: rocfft_aot_helper temp_cachefile.db output_cachefile.db "
             "path/to/rocfft_rtc_helper gfx000 gfx001 ...");
        return 1;
    }

    std::string              temp_cache_file   = argv[1];
    std::string              output_cache_file = argv[2];
    std::string              rtc_helper        = argv[3];
    std::vector<std::string> gpu_archs;
    for(int i = 4; i < argc; ++i)
        gpu_archs.push_back(argv[i]);

    // Default to using a persistent file in the current dir if no
    // cache file was given
    if(temp_cache_file.empty())
    {
        temp_cache_file = "rocfft_temp_cache.db";
    }

    // force RTC to use the temporary cache file
    rocfft_setenv("ROCFFT_RTC_CACHE_PATH", temp_cache_file.c_str());

    // disable system cache since we want to compile everything - use
    // an in-memory DB which will always be empty
    rocfft_setenv("ROCFFT_RTC_SYS_CACHE_PATH", ":memory:");

    // tell RTC where the compile helper is
    rocfft_setenv("ROCFFT_RTC_PROCESS_HELPER", rtc_helper.c_str());

    RTCCache::single = std::make_unique<RTCCache>();

    RTCCache::single->enable_write_mostly();

    CompileQueue queue;

    static const size_t      NUM_THREADS = rocfft_concurrency();
    std::vector<std::thread> threads;
    threads.reserve(NUM_THREADS);
    for(size_t i = 0; i < NUM_THREADS; ++i)
    {
        threads.emplace_back([&queue, &gpu_archs]() {
            while(true)
            {
                auto item = queue.pop();
                if(item.kernel_name.empty())
                    break;
                for(const auto& gpu_arch : gpu_archs)
                    cached_compile(item.kernel_name, gpu_arch, item.generate_src, generator_sum());
            }
        });
    }

    build_stockham_function_pool(queue);
    build_realcomplex(queue);

    // signal end of results with empty work items
    for(size_t i = 0; i < NUM_THREADS; ++i)
        queue.push({});
    for(size_t i = 0; i < NUM_THREADS; ++i)
        threads[i].join();

    // write the output file using what we collected in the temporary
    // cache
    RTCCache::single->write_aot_cache(output_cache_file, generator_sum());

    // try to shrink the temp cache file to 10 GiB
    try
    {
        RTCCache::single->cleanup_cache(static_cast<sqlite3_int64>(10) * 1024 * 1024 * 1024);
    }
    // the build should still succeed even if we fail to shrink the temp cache
    catch(std::exception&)
    {
        std::cerr << "warning: failed to shrink temp cache" << std::endl;
    }

    RTCCache::single.reset();

    return 0;
}
<|endoftext|>


<commit_before>/*** Copyright (c), The Regents of the University of California            ***
 *** For more information please refer to files in the COPYRIGHT directory ***/
/* This is script-generated code (for the most part).  */
/* See modAVUMetadata.h for a description of this API call.*/

#include "modAVUMetadata.hpp"
#include "reFuncDefs.hpp"
#include "reGlobalsExtern.hpp"
#include "icatHighLevelRoutines.hpp"
#include "miscServerFunct.hpp"

int
rsModAVUMetadata( rsComm_t *rsComm, modAVUMetadataInp_t *modAVUMetadataInp ) {
    rodsServerHost_t *rodsServerHost;
    int status;
    char *myHint;

    if ( strcmp( modAVUMetadataInp->arg0, "add" ) == 0 ) {
        myHint = modAVUMetadataInp->arg2;
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "adda" ) == 0 ) {
        myHint = modAVUMetadataInp->arg2;
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "addw" ) == 0 ) {
        myHint = modAVUMetadataInp->arg2;
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "rmw" ) == 0 ) {
        myHint = modAVUMetadataInp->arg2;
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "rmi" ) == 0 ) {
        myHint = modAVUMetadataInp->arg2;
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "rm" ) == 0 ) {
        myHint = modAVUMetadataInp->arg2;
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "cp" ) == 0 ) {
        myHint = modAVUMetadataInp->arg3;
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "mod" ) == 0 ) {
        myHint = modAVUMetadataInp->arg2;
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "set" ) == 0 ) { // JMC - backport 4836
        myHint = modAVUMetadataInp->arg2;
    }
    else {
        /* assume local */
        myHint = NULL;
    }

    status = getAndConnRcatHost( rsComm, MASTER_RCAT, myHint, &rodsServerHost );
    if ( status < 0 ) {
        return( status );
    }

    if ( rodsServerHost->localFlag == LOCAL_HOST ) {
#ifdef RODS_CAT
        status = _rsModAVUMetadata( rsComm, modAVUMetadataInp );
#else
        status = SYS_NO_RCAT_SERVER_ERR;
#endif
    }
    else {
        status = rcModAVUMetadata( rodsServerHost->conn,
                                   modAVUMetadataInp );
    }

    if ( status < 0 ) {
        rodsLog( LOG_NOTICE,
                 "rsModAVUMetadata: rcModAVUMetadata failed" );
    }
    return ( status );
}

#ifdef RODS_CAT

int
_rsModAVUMetadata( rsComm_t *rsComm, modAVUMetadataInp_t *modAVUMetadataInp ) {
    int status, status2;

    char *args[MAX_NUM_OF_ARGS_IN_ACTION];
    int argc;
    ruleExecInfo_t rei2;

    memset( ( char* )&rei2, 0, sizeof( ruleExecInfo_t ) );
    rei2.rsComm = rsComm;
    if ( rsComm != NULL ) {
        rei2.uoic = &rsComm->clientUser;
        rei2.uoip = &rsComm->proxyUser;
    }

    args[0] = modAVUMetadataInp->arg0; /* option add, adda, rm, rmw, rmi, cp,
					  or mod */
    args[1] = modAVUMetadataInp->arg1; /* item type -d,-d,-c,-C,-r,-R,-u,-U */
    args[2] = modAVUMetadataInp->arg2; /* item name */
    args[3] = modAVUMetadataInp->arg3; /* attr name */
    args[4] = modAVUMetadataInp->arg4; /* attr val */
    args[5] = modAVUMetadataInp->arg5;
    if(args[5] == NULL) args[5] = ""; /* attr unit */
    if(strcmp(args[0], "mod") == 0) {
        argc = 9;
#define ARG(arg) if((arg) != NULL && (arg)[0] != '\0') avu[checkModArgType(arg)] = arg
        if(checkModArgType(modAVUMetadataInp->arg5) != 0) {
            char *avu[4] = {"", "", "", ""};
            ARG(modAVUMetadataInp->arg5);
            ARG(modAVUMetadataInp->arg6);
            ARG(modAVUMetadataInp->arg7);
            args[5] = "";
            memcpy(args+6, avu+1, sizeof(char *[3]));
          } else {
              char *avu[4] = {"", "", "", ""};
                ARG(modAVUMetadataInp->arg6); /* new attr */
                ARG(modAVUMetadataInp->arg7); /* new val */
                ARG(modAVUMetadataInp->arg8); /* new unit */
              memcpy(args+6, avu+1, sizeof(char *[3]));
          }
    } else if(strcmp(args[0], "cp") == 0) {
        argc = 5;
    } else {
    argc = 6;
    }

    status2 =  applyRuleArg( "acPreProcForModifyAVUMetadata", args, argc,
                             &rei2, NO_SAVE_REI );
    if ( status2 < 0 ) {
        if ( rei2.status < 0 ) {
            status2 = rei2.status;
        }
        rodsLog( LOG_ERROR,
                 "rsModAVUMetadata:acPreProcForModifyAVUMetadata error for %s of type %s and option %s,stat=%d",
                 modAVUMetadataInp->arg2, modAVUMetadataInp->arg1, modAVUMetadataInp->arg0, status2 );
        return status2;
    }

    if ( strcmp( modAVUMetadataInp->arg0, "add" ) == 0 ) {
        status = chlAddAVUMetadata( rsComm, 0,
                                    modAVUMetadataInp->arg1,
                                    modAVUMetadataInp->arg2,
                                    modAVUMetadataInp->arg3,
                                    modAVUMetadataInp->arg4,
                                    modAVUMetadataInp->arg5 );
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "adda" ) == 0 ) {
        status = chlAddAVUMetadata( rsComm, 1,
                                    modAVUMetadataInp->arg1,
                                    modAVUMetadataInp->arg2,
                                    modAVUMetadataInp->arg3,
                                    modAVUMetadataInp->arg4,
                                    modAVUMetadataInp->arg5 );
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "addw" ) == 0 ) {
        status = chlAddAVUMetadataWild( rsComm, 0,
                                        modAVUMetadataInp->arg1,
                                        modAVUMetadataInp->arg2,
                                        modAVUMetadataInp->arg3,
                                        modAVUMetadataInp->arg4,
                                        modAVUMetadataInp->arg5 );
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "rmw" ) == 0 ) {
        status = chlDeleteAVUMetadata( rsComm, 1,
                                       modAVUMetadataInp->arg1,
                                       modAVUMetadataInp->arg2,
                                       modAVUMetadataInp->arg3,
                                       modAVUMetadataInp->arg4,
                                       modAVUMetadataInp->arg5,
                                       0 );
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "rmi" ) == 0 ) {
        status = chlDeleteAVUMetadata( rsComm, 2,
                                       modAVUMetadataInp->arg1,
                                       modAVUMetadataInp->arg2,
                                       modAVUMetadataInp->arg3,
                                       modAVUMetadataInp->arg4,
                                       modAVUMetadataInp->arg5,
                                       0 );
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "rm" ) == 0 ) {
        status = chlDeleteAVUMetadata( rsComm, 0,
                                       modAVUMetadataInp->arg1,
                                       modAVUMetadataInp->arg2,
                                       modAVUMetadataInp->arg3,
                                       modAVUMetadataInp->arg4,
                                       modAVUMetadataInp->arg5,
                                       0 );
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "cp" ) == 0 ) {
        status = chlCopyAVUMetadata( rsComm,
                                     modAVUMetadataInp->arg1,
                                     modAVUMetadataInp->arg2,
                                     modAVUMetadataInp->arg3,
                                     modAVUMetadataInp->arg4 );
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "mod" ) == 0 ) {
        status = chlModAVUMetadata( rsComm,
                                    modAVUMetadataInp->arg1,
                                    modAVUMetadataInp->arg2,
                                    modAVUMetadataInp->arg3,
                                    modAVUMetadataInp->arg4,
                                    modAVUMetadataInp->arg5,
                                    modAVUMetadataInp->arg6,
                                    modAVUMetadataInp->arg7,
                                    modAVUMetadataInp->arg8 );
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "set" ) == 0 ) { // JMC - backport 4836
        status = chlSetAVUMetadata( rsComm,
                                    modAVUMetadataInp->arg1,
                                    modAVUMetadataInp->arg2,
                                    modAVUMetadataInp->arg3,
                                    modAVUMetadataInp->arg4,
                                    modAVUMetadataInp->arg5 );
    }
    else {
        return( CAT_INVALID_ARGUMENT );
    }

    if ( status >= 0 ) {
        status2 =  applyRuleArg( "acPostProcForModifyAVUMetadata", args, argc, &rei2, NO_SAVE_REI );
        if ( status2 < 0 ) {
            if ( rei2.status < 0 ) {
                status2 = rei2.status;
            }
            rodsLog( LOG_ERROR,
                     "rsModAVUMetadata:acPostProcForModifyAVUMetadata error for %s of type %s and option %s,stat=%d",
                     modAVUMetadataInp->arg2,
                     modAVUMetadataInp->arg1,
                     modAVUMetadataInp->arg0,
                     status2 );
            return status2;
        }
    }

    return( status );

}
#endif
<commit_msg>[#2212] CID25926:<commit_after>/*** Copyright (c), The Regents of the University of California            ***
 *** For more information please refer to files in the COPYRIGHT directory ***/
/* This is script-generated code (for the most part).  */
/* See modAVUMetadata.h for a description of this API call.*/

#include "modAVUMetadata.hpp"
#include "reFuncDefs.hpp"
#include "reGlobalsExtern.hpp"
#include "icatHighLevelRoutines.hpp"
#include "miscServerFunct.hpp"

int
rsModAVUMetadata( rsComm_t *rsComm, modAVUMetadataInp_t *modAVUMetadataInp ) {
    rodsServerHost_t *rodsServerHost;
    int status;
    char *myHint;

    if ( strcmp( modAVUMetadataInp->arg0, "add" ) == 0 ) {
        myHint = modAVUMetadataInp->arg2;
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "adda" ) == 0 ) {
        myHint = modAVUMetadataInp->arg2;
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "addw" ) == 0 ) {
        myHint = modAVUMetadataInp->arg2;
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "rmw" ) == 0 ) {
        myHint = modAVUMetadataInp->arg2;
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "rmi" ) == 0 ) {
        myHint = modAVUMetadataInp->arg2;
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "rm" ) == 0 ) {
        myHint = modAVUMetadataInp->arg2;
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "cp" ) == 0 ) {
        myHint = modAVUMetadataInp->arg3;
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "mod" ) == 0 ) {
        myHint = modAVUMetadataInp->arg2;
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "set" ) == 0 ) { // JMC - backport 4836
        myHint = modAVUMetadataInp->arg2;
    }
    else {
        /* assume local */
        myHint = NULL;
    }

    status = getAndConnRcatHost( rsComm, MASTER_RCAT, myHint, &rodsServerHost );
    if ( status < 0 ) {
        return( status );
    }

    if ( rodsServerHost->localFlag == LOCAL_HOST ) {
#ifdef RODS_CAT
        status = _rsModAVUMetadata( rsComm, modAVUMetadataInp );
#else
        status = SYS_NO_RCAT_SERVER_ERR;
#endif
    }
    else {
        status = rcModAVUMetadata( rodsServerHost->conn,
                                   modAVUMetadataInp );
    }

    if ( status < 0 ) {
        rodsLog( LOG_NOTICE,
                 "rsModAVUMetadata: rcModAVUMetadata failed" );
    }
    return ( status );
}

#ifdef RODS_CAT

int
_rsModAVUMetadata( rsComm_t *rsComm, modAVUMetadataInp_t *modAVUMetadataInp ) {
    int status, status2;

    char *args[MAX_NUM_OF_ARGS_IN_ACTION];
    int argc;
    ruleExecInfo_t rei2;

    memset( ( char* )&rei2, 0, sizeof( ruleExecInfo_t ) );
    rei2.rsComm = rsComm;
    if ( rsComm != NULL ) {
        rei2.uoic = &rsComm->clientUser;
        rei2.uoip = &rsComm->proxyUser;
    }

    args[0] = modAVUMetadataInp->arg0; /* option add, adda, rm, rmw, rmi, cp,
					  or mod */
    args[1] = modAVUMetadataInp->arg1; /* item type -d,-d,-c,-C,-r,-R,-u,-U */
    args[2] = modAVUMetadataInp->arg2; /* item name */
    args[3] = modAVUMetadataInp->arg3; /* attr name */
    args[4] = modAVUMetadataInp->arg4; /* attr val */
    args[5] = modAVUMetadataInp->arg5;
    if(args[5] == NULL) args[5] = ""; /* attr unit */
    if(strcmp(args[0], "mod") == 0) {
        argc = 9;
#define ARG(arg) { int ix; if( ( ix = checkModArgType(arg) ) >= 0 ) avu[ix] = arg; }
        if(checkModArgType(modAVUMetadataInp->arg5) != 0) {
            char *avu[4] = {"", "", "", ""};
            ARG(modAVUMetadataInp->arg5);
            ARG(modAVUMetadataInp->arg6);
            ARG(modAVUMetadataInp->arg7);
            args[5] = "";
            memcpy(args+6, avu+1, sizeof(char *[3]));
          } else {
              char *avu[4] = {"", "", "", ""};
                ARG(modAVUMetadataInp->arg6); /* new attr */
                ARG(modAVUMetadataInp->arg7); /* new val */
                ARG(modAVUMetadataInp->arg8); /* new unit */
              memcpy(args+6, avu+1, sizeof(char *[3]));
          }
    } else if(strcmp(args[0], "cp") == 0) {
        argc = 5;
    } else {
    argc = 6;
    }

    status2 =  applyRuleArg( "acPreProcForModifyAVUMetadata", args, argc,
                             &rei2, NO_SAVE_REI );
    if ( status2 < 0 ) {
        if ( rei2.status < 0 ) {
            status2 = rei2.status;
        }
        rodsLog( LOG_ERROR,
                 "rsModAVUMetadata:acPreProcForModifyAVUMetadata error for %s of type %s and option %s,stat=%d",
                 modAVUMetadataInp->arg2, modAVUMetadataInp->arg1, modAVUMetadataInp->arg0, status2 );
        return status2;
    }

    if ( strcmp( modAVUMetadataInp->arg0, "add" ) == 0 ) {
        status = chlAddAVUMetadata( rsComm, 0,
                                    modAVUMetadataInp->arg1,
                                    modAVUMetadataInp->arg2,
                                    modAVUMetadataInp->arg3,
                                    modAVUMetadataInp->arg4,
                                    modAVUMetadataInp->arg5 );
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "adda" ) == 0 ) {
        status = chlAddAVUMetadata( rsComm, 1,
                                    modAVUMetadataInp->arg1,
                                    modAVUMetadataInp->arg2,
                                    modAVUMetadataInp->arg3,
                                    modAVUMetadataInp->arg4,
                                    modAVUMetadataInp->arg5 );
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "addw" ) == 0 ) {
        status = chlAddAVUMetadataWild( rsComm, 0,
                                        modAVUMetadataInp->arg1,
                                        modAVUMetadataInp->arg2,
                                        modAVUMetadataInp->arg3,
                                        modAVUMetadataInp->arg4,
                                        modAVUMetadataInp->arg5 );
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "rmw" ) == 0 ) {
        status = chlDeleteAVUMetadata( rsComm, 1,
                                       modAVUMetadataInp->arg1,
                                       modAVUMetadataInp->arg2,
                                       modAVUMetadataInp->arg3,
                                       modAVUMetadataInp->arg4,
                                       modAVUMetadataInp->arg5,
                                       0 );
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "rmi" ) == 0 ) {
        status = chlDeleteAVUMetadata( rsComm, 2,
                                       modAVUMetadataInp->arg1,
                                       modAVUMetadataInp->arg2,
                                       modAVUMetadataInp->arg3,
                                       modAVUMetadataInp->arg4,
                                       modAVUMetadataInp->arg5,
                                       0 );
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "rm" ) == 0 ) {
        status = chlDeleteAVUMetadata( rsComm, 0,
                                       modAVUMetadataInp->arg1,
                                       modAVUMetadataInp->arg2,
                                       modAVUMetadataInp->arg3,
                                       modAVUMetadataInp->arg4,
                                       modAVUMetadataInp->arg5,
                                       0 );
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "cp" ) == 0 ) {
        status = chlCopyAVUMetadata( rsComm,
                                     modAVUMetadataInp->arg1,
                                     modAVUMetadataInp->arg2,
                                     modAVUMetadataInp->arg3,
                                     modAVUMetadataInp->arg4 );
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "mod" ) == 0 ) {
        status = chlModAVUMetadata( rsComm,
                                    modAVUMetadataInp->arg1,
                                    modAVUMetadataInp->arg2,
                                    modAVUMetadataInp->arg3,
                                    modAVUMetadataInp->arg4,
                                    modAVUMetadataInp->arg5,
                                    modAVUMetadataInp->arg6,
                                    modAVUMetadataInp->arg7,
                                    modAVUMetadataInp->arg8 );
    }
    else if ( strcmp( modAVUMetadataInp->arg0, "set" ) == 0 ) { // JMC - backport 4836
        status = chlSetAVUMetadata( rsComm,
                                    modAVUMetadataInp->arg1,
                                    modAVUMetadataInp->arg2,
                                    modAVUMetadataInp->arg3,
                                    modAVUMetadataInp->arg4,
                                    modAVUMetadataInp->arg5 );
    }
    else {
        return( CAT_INVALID_ARGUMENT );
    }

    if ( status >= 0 ) {
        status2 =  applyRuleArg( "acPostProcForModifyAVUMetadata", args, argc, &rei2, NO_SAVE_REI );
        if ( status2 < 0 ) {
            if ( rei2.status < 0 ) {
                status2 = rei2.status;
            }
            rodsLog( LOG_ERROR,
                     "rsModAVUMetadata:acPostProcForModifyAVUMetadata error for %s of type %s and option %s,stat=%d",
                     modAVUMetadataInp->arg2,
                     modAVUMetadataInp->arg1,
                     modAVUMetadataInp->arg0,
                     status2 );
            return status2;
        }
    }

    return( status );

}
#endif
<|endoftext|>


<commit_before>/*
 * Copyright © 2010 Intel Corporation
 *
 * 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 (including the next
 * paragraph) 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.
 */

/**
 * \file ir_constant_folding.cpp
 * Replace constant-valued expressions with references to constant values.
 */

#define NULL 0
#include "ir.h"
#include "ir_visitor.h"
#include "ir_constant_folding.h"
#include "glsl_types.h"

/**
 * Visitor class for replacing expressions with ir_constant values.
 */

void
ir_constant_folding_visitor::visit(ir_variable *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_label *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_function_signature *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_function *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_expression *ir)
{
   ir_constant *op[2];
   unsigned int operand;

   for (operand = 0; operand < ir->get_num_operands(); operand++) {
      op[operand] = ir->operands[operand]->constant_expression_value();
      if (op[operand]) {
	 ir->operands[operand] = op[operand];
      }
   }
}

void
ir_constant_folding_visitor::visit(ir_swizzle *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_dereference *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_assignment *ir)
{
   ir_constant *const_val = ir->rhs->constant_expression_value();
   if (const_val)
      ir->rhs = const_val;
   else
      ir->rhs->accept(this);
}

void
ir_constant_folding_visitor::visit(ir_constant *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_call *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_return *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_if *ir)
{
   (void) ir;
}
<commit_msg>Fold constant expressions in if conditionals.<commit_after>/*
 * Copyright © 2010 Intel Corporation
 *
 * 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 (including the next
 * paragraph) 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.
 */

/**
 * \file ir_constant_folding.cpp
 * Replace constant-valued expressions with references to constant values.
 */

#define NULL 0
#include "ir.h"
#include "ir_visitor.h"
#include "ir_constant_folding.h"
#include "glsl_types.h"

/**
 * Visitor class for replacing expressions with ir_constant values.
 */

void
ir_constant_folding_visitor::visit(ir_variable *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_label *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_function_signature *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_function *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_expression *ir)
{
   ir_constant *op[2];
   unsigned int operand;

   for (operand = 0; operand < ir->get_num_operands(); operand++) {
      op[operand] = ir->operands[operand]->constant_expression_value();
      if (op[operand]) {
	 ir->operands[operand] = op[operand];
      }
   }
}

void
ir_constant_folding_visitor::visit(ir_swizzle *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_dereference *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_assignment *ir)
{
   ir_constant *const_val = ir->rhs->constant_expression_value();
   if (const_val)
      ir->rhs = const_val;
   else
      ir->rhs->accept(this);
}

void
ir_constant_folding_visitor::visit(ir_constant *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_call *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_return *ir)
{
   (void) ir;
}

void
ir_constant_folding_visitor::visit(ir_if *ir)
{
   ir_constant *const_val = ir->condition->constant_expression_value();
   if (const_val)
      ir->condition = const_val;
   else
      ir->condition->accept(this);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdint>

#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>

#include "vulkanwrapper/Instance.hpp"
#include <gtest/gtest.h>

namespace
{

class InstanceTest : public ::testing::Test
{
protected:

	static void errorCallback (int error, const char *description)
	{
		std::cerr << "GLFW error: " << error << "; " << description << std::endl;
	}

	static void * getInstanceProcAddrWrapper (VkInstance instance, const char *pname)
	{
		return (void *) glfwGetInstanceProcAddress(instance, pname);
	}

	virtual void SetUp ()
	{
		ASSERT_EQ(glfwInit(), GLFW_TRUE) << "Could not initialize GLFW";
		ASSERT_EQ(glfwVulkanSupported(), GLFW_TRUE) << "Vulkan is not supported";
	}

	virtual void TearDown ()
	{
		glfwTerminate();
	}
};

} // anonymous

TEST_F(InstanceTest, InstanceCreation)
{
	PFN_vkCreateInstance vkCreateInstance = (PFN_vkCreateInstance) glfwGetInstanceProcAddress(nullptr, "vkCreateInstance");
	ASSERT_NE(vkCreateInstance, nullptr) << "Could not get pointer for vkCreateInstance";

	std::uint32_t glfwExtensionCount;
	const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
	ASSERT_NE(glfwExtensions, nullptr) << "Could not get GLFW required extensions";

	std::vector<const char *> extensions;

	for (unsigned int i = 0; i < glfwExtensionCount; ++i)
	{
		extensions.push_back(glfwExtensions[i]);
	}

	VkInstanceCreateInfo instanceCreateInfo =
		{
			VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// sType
			nullptr,								// pNext
			0,										// flags
			nullptr,								// pApplicationInfo
		    0,										// enabledLayerCount
		    nullptr,								// ppEnabledLayerNames
		    (uint32_t) extensions.size(),			// enabledExtensionCount
			extensions.data(),						// ppEnabledExtensionNames
		};

	VkInstance instanceHandle;
	ASSERT_EQ(vkCreateInstance(&instanceCreateInfo, nullptr, &instanceHandle), VK_SUCCESS) << "Could not create Vulkan instance";

	vkw::Instance instance;

	ASSERT_NO_THROW(instance = vkw::Instance(instanceHandle, getInstanceProcAddrWrapper));
}
<commit_msg>Test with and without layers and extensions<commit_after>#include <iostream>
#include <cstdint>

#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>

#include "vulkanwrapper/Instance.hpp"
#include <gtest/gtest.h>

namespace
{

class InstanceTest : public ::testing::Test
{
protected:

	static void errorCallback (int error, const char *description)
	{
		std::cerr << "GLFW error: " << error << "; " << description << std::endl;
	}

	static void * getInstanceProcAddrWrapper (VkInstance instance, const char *pname)
	{
		return (void *) glfwGetInstanceProcAddress(instance, pname);
	}

    void createInstance (const char **extensions, unsigned int extensionCount,
						 const char **layers, unsigned int layerCount,
						 vkw::Instance& instance) const
	{
		PFN_vkCreateInstance vkCreateInstance = (PFN_vkCreateInstance) glfwGetInstanceProcAddress(nullptr, "vkCreateInstance");
		ASSERT_NE(vkCreateInstance, nullptr) << "Could not get pointer for vkCreateInstance";

		std::uint32_t glfwExtensionCount;
		const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
		ASSERT_NE(glfwExtensions, nullptr) << "Could not get GLFW required extensions";

		std::vector<const char *> allExtensions;

		for (unsigned int i = 0; i < glfwExtensionCount; ++i)
		{
			allExtensions.push_back(glfwExtensions[i]);
		}

		for (unsigned int i = 0; i < extensionCount; ++i)
		{
			allExtensions.push_back(extensions[i]);
		}

		VkInstanceCreateInfo instanceCreateInfo =
			{
				VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,	// sType
				nullptr,								// pNext
				0,										// flags
				nullptr,								// pApplicationInfo
				(std::uint32_t) layerCount,				// enabledLayerCount
				layers,									// ppEnabledLayerNames
				(std::uint32_t) allExtensions.size(),	// enabledExtensionCount
				allExtensions.data(),					// ppEnabledExtensionNames
			};

		VkInstance instanceHandle;
		ASSERT_EQ(vkCreateInstance(&instanceCreateInfo, nullptr, &instanceHandle), VK_SUCCESS) << "Could not create Vulkan instance";

	    instance = vkw::Instance(instanceHandle, getInstanceProcAddrWrapper);
	}

	virtual void SetUp ()
	{
		ASSERT_EQ(glfwInit(), GLFW_TRUE) << "Could not initialize GLFW";
		ASSERT_EQ(glfwVulkanSupported(), GLFW_TRUE) << "Vulkan is not supported";
	}

	virtual void TearDown ()
	{
		glfwTerminate();
	}
};

} // anonymous

TEST_F(InstanceTest, InstanceCreation)
{
	vkw::Instance instance;
	ASSERT_NO_THROW(createInstance(nullptr, 0, nullptr, 0, instance));
}

TEST_F(InstanceTest, InstanceCreationLayers)
{
	const char *extensions[] =
		{
			"VK_EXT_debug_report"
		};

	const char *layers[] =
		{
			"VK_LAYER_LUNARG_standard_validation"
		};

	vkw::Instance instance;
	ASSERT_NO_THROW(createInstance(extensions, 1, layers, 1, instance));
}
<|endoftext|>


<commit_before>/**
 * @file   JsonUtilsTest.cpp
 * @brief  JsonUtils class tester.
 * @author zer0
 * @date   2019-06-16
 */

#include <gtest/gtest.h>
#include <libtbag/dom/json/JsonUtils.hpp>

using namespace libtbag;
using namespace libtbag::dom;
using namespace libtbag::dom::json;

TEST(JsonUtilsTest, Path)
{
    char const * const TEST_JSON_TEXT = R"(
{
    "key1": { "temp": 1 },
    "key2": { "temp": 2 },
    "key3": { "temp": 3 }
})";
    Json::Value original;
    ASSERT_TRUE(parse(TEST_JSON_TEXT, original));

    Json::Path path1(".key1.temp");
    auto const value1 = path1.make(original);
    ASSERT_TRUE(value1.isInt());
    ASSERT_EQ(1, value1.asInt());

    Json::Path path2(".key2.temp");
    auto const value2 = path2.make(original);
    ASSERT_TRUE(value2.isInt());
    ASSERT_EQ(2, value2.asInt());

    Json::Path path3(".key3.temp");
    auto const value3 = path3.make(original);
    ASSERT_TRUE(value3.isInt());
    ASSERT_EQ(3, value3.asInt());

    Json::Path path_error(".test");
    auto const value_error = path_error.make(original);
    ASSERT_TRUE(value_error.isNull());
}

TEST(JsonUtilsTest, Default)
{
    char const * const TEST_JSON_TEXT = R"({"key":"value"})";
    Json::Value value;
    ASSERT_TRUE(parse(TEST_JSON_TEXT, value));
    auto const JSON_TEXT = writeFast(value);
    ASSERT_STREQ(TEST_JSON_TEXT, JSON_TEXT.c_str());
}

TEST(JsonUtilsTest, DoNotUseTheDropNull)
{
    char const * const TEST_JSON_TEXT = R"({"key":null})";
    Json::Value value;
    ASSERT_TRUE(parse(TEST_JSON_TEXT, value));
    auto const JSON_TEXT = writeFast(value);
    ASSERT_STREQ(TEST_JSON_TEXT, JSON_TEXT.c_str());
}

TEST(JsonUtilsTest, OptErr)
{
    char const * const TEST_JSON_TEXT = R"({"key":"warning"})";
    Json::Value value;
    ASSERT_TRUE(parse(TEST_JSON_TEXT, value));
    ASSERT_EQ(E_WARNING, optErr(value["key"]));
}

TEST(JsonUtilsTest, GetString)
{
    ASSERT_STREQ("test", getForceString(getJsonValue("\"test\"")).c_str());
    ASSERT_STREQ("0.1", getForceString(getJsonValue("0.1")).c_str());
}

TEST(JsonUtilsTest, GetStringArray)
{
    char const * const TEST_JSON_TEXT = R"(["test", 0.1, 99, "a", null, "b"])";
    Json::Value value;
    ASSERT_TRUE(parse(TEST_JSON_TEXT, value));
    auto const result = getStringArray(value);
    ASSERT_EQ(6, result.size());
    ASSERT_STREQ("test", result[0].c_str());
    ASSERT_STREQ("0.1", result[1].c_str());
    ASSERT_STREQ("99", result[2].c_str());
    ASSERT_STREQ("a", result[3].c_str());
    ASSERT_STREQ("", result[4].c_str());
    ASSERT_STREQ("b", result[5].c_str());
}

TEST(JsonUtilsTest, toJsonArray)
{
    auto const json = toJsonArray(std::vector<int>({10, 20, 30}));
    ASSERT_TRUE(json.isArray());
    ASSERT_EQ(3, json.size());
    ASSERT_EQ(10, json[0].asInt());
    ASSERT_EQ(20, json[1].asInt());
    ASSERT_EQ(30, json[2].asInt());
}

TEST(JsonUtilsTest, toJsonObject_1)
{
    auto const json = toJsonObject(std::map<std::string, std::string>({ {"A","B"}, {"C","D"} }));
    ASSERT_TRUE(json.isObject());
    ASSERT_EQ(2, json.size());
    ASSERT_STREQ("B", json["A"].asCString());
    ASSERT_STREQ("D", json["C"].asCString());
}

TEST(JsonUtilsTest, toJsonObject_2)
{
    auto const json = toJsonObject(std::unordered_map<std::string, std::string>({ {"A","B"}, {"C","D"} }));
    ASSERT_TRUE(json.isObject());
    ASSERT_EQ(2, json.size());
    ASSERT_STREQ("B", json["A"].asCString());
    ASSERT_STREQ("D", json["C"].asCString());
}

TEST(JsonUtilsTest, getStringMap)
{
    char const * const TEST_JSON_TEXT = R"(
{
    "key1": "temp1",
    "key2": "temp2",
    "key3": "temp3"
})";
    Json::Value original;
    ASSERT_TRUE(parse(TEST_JSON_TEXT, original));

    auto result = getStringMap(original);
    ASSERT_EQ(3, result.size());
    ASSERT_STREQ("temp1", result["key1"].c_str());
    ASSERT_STREQ("temp2", result["key2"].c_str());
    ASSERT_STREQ("temp3", result["key3"].c_str());
}

<commit_msg>Create JsonUtilsTest.Example_Foreach_Object tester.<commit_after>/**
 * @file   JsonUtilsTest.cpp
 * @brief  JsonUtils class tester.
 * @author zer0
 * @date   2019-06-16
 */

#include <gtest/gtest.h>
#include <libtbag/dom/json/JsonUtils.hpp>

using namespace libtbag;
using namespace libtbag::dom;
using namespace libtbag::dom::json;

TEST(JsonUtilsTest, Example_Foreach_Object)
{
    char const * const TEST_JSON_TEXT = R"(
{
    "key1": { "temp": 1 },
    "key2": { "temp": 2 }
})";

    Json::Value json;
    ASSERT_TRUE(parse(TEST_JSON_TEXT, json));

    auto itr = json.begin();
    auto const end = json.end();
    for (; itr != end; ++itr) {
        std::cout << "Key: " << itr.key() << std::endl;
        assert(itr->isObject());
        std::cout << "Value['temp']: " << (*itr)["temp"].asInt() << std::endl;
    }
}

TEST(JsonUtilsTest, Path)
{
    char const * const TEST_JSON_TEXT = R"(
{
    "key1": { "temp": 1 },
    "key2": { "temp": 2 },
    "key3": { "temp": 3 }
})";
    Json::Value original;
    ASSERT_TRUE(parse(TEST_JSON_TEXT, original));

    Json::Path path1(".key1.temp");
    auto const value1 = path1.make(original);
    ASSERT_TRUE(value1.isInt());
    ASSERT_EQ(1, value1.asInt());

    Json::Path path2(".key2.temp");
    auto const value2 = path2.make(original);
    ASSERT_TRUE(value2.isInt());
    ASSERT_EQ(2, value2.asInt());

    Json::Path path3(".key3.temp");
    auto const value3 = path3.make(original);
    ASSERT_TRUE(value3.isInt());
    ASSERT_EQ(3, value3.asInt());

    Json::Path path_error(".test");
    auto const value_error = path_error.make(original);
    ASSERT_TRUE(value_error.isNull());
}

TEST(JsonUtilsTest, Default)
{
    char const * const TEST_JSON_TEXT = R"({"key":"value"})";
    Json::Value value;
    ASSERT_TRUE(parse(TEST_JSON_TEXT, value));
    auto const JSON_TEXT = writeFast(value);
    ASSERT_STREQ(TEST_JSON_TEXT, JSON_TEXT.c_str());
}

TEST(JsonUtilsTest, DoNotUseTheDropNull)
{
    char const * const TEST_JSON_TEXT = R"({"key":null})";
    Json::Value value;
    ASSERT_TRUE(parse(TEST_JSON_TEXT, value));
    auto const JSON_TEXT = writeFast(value);
    ASSERT_STREQ(TEST_JSON_TEXT, JSON_TEXT.c_str());
}

TEST(JsonUtilsTest, OptErr)
{
    char const * const TEST_JSON_TEXT = R"({"key":"warning"})";
    Json::Value value;
    ASSERT_TRUE(parse(TEST_JSON_TEXT, value));
    ASSERT_EQ(E_WARNING, optErr(value["key"]));
}

TEST(JsonUtilsTest, GetString)
{
    ASSERT_STREQ("test", getForceString(getJsonValue("\"test\"")).c_str());
    ASSERT_STREQ("0.1", getForceString(getJsonValue("0.1")).c_str());
}

TEST(JsonUtilsTest, GetStringArray)
{
    char const * const TEST_JSON_TEXT = R"(["test", 0.1, 99, "a", null, "b"])";
    Json::Value value;
    ASSERT_TRUE(parse(TEST_JSON_TEXT, value));
    auto const result = getStringArray(value);
    ASSERT_EQ(6, result.size());
    ASSERT_STREQ("test", result[0].c_str());
    ASSERT_STREQ("0.1", result[1].c_str());
    ASSERT_STREQ("99", result[2].c_str());
    ASSERT_STREQ("a", result[3].c_str());
    ASSERT_STREQ("", result[4].c_str());
    ASSERT_STREQ("b", result[5].c_str());
}

TEST(JsonUtilsTest, toJsonArray)
{
    auto const json = toJsonArray(std::vector<int>({10, 20, 30}));
    ASSERT_TRUE(json.isArray());
    ASSERT_EQ(3, json.size());
    ASSERT_EQ(10, json[0].asInt());
    ASSERT_EQ(20, json[1].asInt());
    ASSERT_EQ(30, json[2].asInt());
}

TEST(JsonUtilsTest, toJsonObject_1)
{
    auto const json = toJsonObject(std::map<std::string, std::string>({ {"A","B"}, {"C","D"} }));
    ASSERT_TRUE(json.isObject());
    ASSERT_EQ(2, json.size());
    ASSERT_STREQ("B", json["A"].asCString());
    ASSERT_STREQ("D", json["C"].asCString());
}

TEST(JsonUtilsTest, toJsonObject_2)
{
    auto const json = toJsonObject(std::unordered_map<std::string, std::string>({ {"A","B"}, {"C","D"} }));
    ASSERT_TRUE(json.isObject());
    ASSERT_EQ(2, json.size());
    ASSERT_STREQ("B", json["A"].asCString());
    ASSERT_STREQ("D", json["C"].asCString());
}

TEST(JsonUtilsTest, getStringMap)
{
    char const * const TEST_JSON_TEXT = R"(
{
    "key1": "temp1",
    "key2": "temp2",
    "key3": "temp3"
})";
    Json::Value original;
    ASSERT_TRUE(parse(TEST_JSON_TEXT, original));

    auto result = getStringMap(original);
    ASSERT_EQ(3, result.size());
    ASSERT_STREQ("temp1", result["key1"].c_str());
    ASSERT_STREQ("temp2", result["key2"].c_str());
    ASSERT_STREQ("temp3", result["key3"].c_str());
}

<|endoftext|>


<commit_before>#ifndef BULL_NETWORK_SOCKET_TCPSERVER_HPP
#define BULL_NETWORK_SOCKET_TCPSERVER_HPP

#include <Bull/Core/Time/Duration.hpp>

#include <Bull/Network/Address/IpAddressWrapper.hpp>
#include <Bull/Network/Socket/Socket.hpp>
#include <Bull/Network/Socket/SocketState.hpp>

namespace Bull
{
    class TcpClient;

    namespace prv
    {
        class TcpServerImpl;
    }

    class BULL_NETWORK_API TcpServer : public Socket
    {
    public:

        /*! \brief Default constructor
         *
         */
        TcpServer();

        /*! \brief Constructor by movement
         *
         * \param move The TcpServer to move
         *
         */
        TcpServer(TcpServer&& move) noexcept = default;

        /*! \brief Destructor
         *
         */
        ~TcpServer();

        /*! \brief Basic assignment operator by movement
         *
         * \param move The TcpServer to move
         *
         * \return This
         *
         */
        TcpServer& operator=(TcpServer&& move) noexcept = default;

        /*! \brief Start to listen a NetPort
         *
         * \param port    The NetPort to listen
         * \param host    The host to listen
         * \param backlog The number of simultaneous active connection on the TcpServer
         *
         * \return The new SocketState
         *
         */
        SocketState listen(NetPort port, const IpAddressWrapper& host = IpAddressV4::Any, int backlog = -1);

        /*! \brief Tell whether the TcpServer is listening a NetPort
         *
         * \return True if the TcpServer is listening
         *
         */
        bool isListening() const;

        /*! \brief Accept an incoming connection
         *
         * \param client The client to accept
         *
         * \return The new SocketState
         *
         */
        SocketState accept(TcpClient& client);

        /*! \brief Accept an incoming connection
         *
         * \param client  The client to accept
         * \param timeout The time before the function fail
         * \param pause   The time between two try
         *
         * \return The new SocketState
         *
         */
        SocketState accept(TcpClient& client, const Duration& timeout, const Duration& pause = Duration::milliseconds(20.f));

        /*! \brief Disconnect the TcpServer
         *
         */
        void disconnect();

        /*! \brief The number of simultaneous active connection on the TcpServer
         *
         * \return The number of simultaneous active connection
         *
         */
        int getBacklog() const;

        /*! \brief Get the NetPort listened by the TcpServer
         *
         * \return The NetPort
         *
         */
        NetPort getPort() const;

    private:

        std::unique_ptr<prv::TcpServerImpl> m_impl;
        NetPort                             m_port;
        int                                 m_backlog;
    };
}

#endif // BULL_NETWORK_SOCKET_TCPSERVER_HPP
<commit_msg>[Network/TcpServer] Add a constant to represent an unlimited backlog<commit_after>#ifndef BULL_NETWORK_SOCKET_TCPSERVER_HPP
#define BULL_NETWORK_SOCKET_TCPSERVER_HPP

#include <Bull/Core/Time/Duration.hpp>

#include <Bull/Network/Address/IpAddressWrapper.hpp>
#include <Bull/Network/Socket/Socket.hpp>
#include <Bull/Network/Socket/SocketState.hpp>

namespace Bull
{
    class TcpClient;

    namespace prv
    {
        class TcpServerImpl;
    }

    class BULL_NETWORK_API TcpServer : public Socket
    {
    public:

        static constexpr int UnlimitedBacklog = -1;

    public:

        /*! \brief Default constructor
         *
         */
        TcpServer();

        /*! \brief Constructor by movement
         *
         * \param move The TcpServer to move
         *
         */
        TcpServer(TcpServer&& move) noexcept = default;

        /*! \brief Destructor
         *
         */
        ~TcpServer();

        /*! \brief Basic assignment operator by movement
         *
         * \param move The TcpServer to move
         *
         * \return This
         *
         */
        TcpServer& operator=(TcpServer&& move) noexcept = default;

        /*! \brief Start to listen a NetPort
         *
         * \param port    The NetPort to listen
         * \param host    The host to listen
         * \param backlog The number of simultaneous active connection on the TcpServer
         *
         * \return The new SocketState
         *
         */
        SocketState listen(NetPort port, const IpAddressWrapper& host = IpAddressV4::Any, int backlog = UnlimitedBacklog);

        /*! \brief Tell whether the TcpServer is listening a NetPort
         *
         * \return True if the TcpServer is listening
         *
         */
        bool isListening() const;

        /*! \brief Accept an incoming connection
         *
         * \param client The client to accept
         *
         * \return The new SocketState
         *
         */
        SocketState accept(TcpClient& client);

        /*! \brief Accept an incoming connection
         *
         * \param client  The client to accept
         * \param timeout The time before the function fail
         * \param pause   The time between two try
         *
         * \return The new SocketState
         *
         */
        SocketState accept(TcpClient& client, const Duration& timeout, const Duration& pause = Duration::milliseconds(20.f));

        /*! \brief Disconnect the TcpServer
         *
         */
        void disconnect();

        /*! \brief The number of simultaneous active connection on the TcpServer
         *
         * \return The number of simultaneous active connection
         *
         */
        int getBacklog() const;

        /*! \brief Get the NetPort listened by the TcpServer
         *
         * \return The NetPort
         *
         */
        NetPort getPort() const;

    private:

        std::unique_ptr<prv::TcpServerImpl> m_impl;
        NetPort                             m_port;
        int                                 m_backlog;
    };
}

#endif // BULL_NETWORK_SOCKET_TCPSERVER_HPP
<|endoftext|>


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

#ifndef IE_CORE_RGBTOXYZCOLORTRANSFORM_INL
#define IE_CORE_RGBTOXYZCOLORTRANSFORM_INL

#include <cassert>

#include "OpenEXR/ImathVec.h"

#include "IECore/Convert.h"
#include "IECore/VectorTraits.h"

namespace IECore
{

template<typename F, typename T>
RGBToXYZColorTransform<F, T>::RGBToXYZColorTransform()
{
	setMatrix(
		Imath::V2f( 0.64, 0.33 ),
		Imath::V2f( 0.3, 0.6 ),
		Imath::V2f( 0.15, 0.06 ),
		Imath::V2f( 0.312713, 0.329016 )

	);
}

template<typename F, typename T>
template<typename M>
RGBToXYZColorTransform<F, T>::RGBToXYZColorTransform( const M &matrix )
{
	m_matrix = convert<Imath::M33f>( matrix );
}

template<typename F, typename T>
template<typename C>
RGBToXYZColorTransform<F, T>::RGBToXYZColorTransform(
	const C &rChromacity,
	const C &gChromacity,
	const C &bChromacity,

	const C &referenceWhite
)
{
	setMatrix( rChromacity, gChromacity, bChromacity, referenceWhite );
}

template<typename F, typename T>
template<typename C>
void RGBToXYZColorTransform<F, T>::setMatrix(
	const C &rChromacity,
	const C &gChromacity,
	const C &bChromacity,

	const C &referenceWhite
)
{
	BOOST_STATIC_ASSERT( ( TypeTraits::IsVec2<C>::value ) );

	typedef VectorTraits<C> VecTraits;

	/// \todo Implement this in terms of an xyY->XYZ converter
	float xr = VecTraits::get( rChromacity, 0 );
	float yr = VecTraits::get( rChromacity, 1 );

	float xg = VecTraits::get( gChromacity, 0 );
	float yg = VecTraits::get( gChromacity, 1 );

	float xb = VecTraits::get( bChromacity, 0 );
	float yb = VecTraits::get( bChromacity, 1 );

	float xw = VecTraits::get( referenceWhite, 0 );
	float yw = VecTraits::get( referenceWhite, 1 );

	float Xr = xr / yr;
	float Yr = 1.0;
	float Zr = ( 1.0 - xr - yr ) / yr;

	float Xg = xg / yg;
	float Yg = 1.0;
	float Zg = ( 1.0 - xg - yg ) / yg;

	float Xb = xb / yb;
	float Yb = 1.0;
	float Zb = ( 1.0 - xb - yb ) / yb;

	float Xw = xw / yw;
	float Yw = 1.0;
	float Zw = ( 1.0 - xw - yw ) / yw;

	Imath::M33f m = Imath::M33f
		(
			Xr, Yr, Zr,
			Xg, Yg, Zg,
			Xb, Yb, Zb
		).inverse();

	Imath::V3f rw( Xw, Yw, Zw );

	Imath::V3f s = rw * m;

	float Sr = s.x;
	float Sg = s.y;
	float Sb = s.z;

	m_matrix = Imath::M33f
	(
		Sr * Xr, Sr * Yr, Sr * Zr,
		Sg * Xg, Sg * Yg, Sg * Zg,
		Sb * Xb, Sb * Yb, Sb * Zb
	);

}

template<typename F, typename T>
T RGBToXYZColorTransform<F, T>::operator()( F f )
{
	Imath::V3f from = IECore::convert< Imath::V3f >( f );

	return IECore::convert<T>( from * m_matrix );
}

template<typename F, typename T>
typename RGBToXYZColorTransform<F, T>::InverseType RGBToXYZColorTransform<F, T>::inverse() const
{
	return InverseType( m_matrix.inverse() );
}

template<typename F, typename T>
const Imath::M33f &RGBToXYZColorTransform<F, T>::matrix() const
{
	return m_matrix;
}

} // namespace IECore

#endif // IE_CORE_RGBTOXYZCOLORTRANSFORM_INL

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

#ifndef IE_CORE_RGBTOXYZCOLORTRANSFORM_INL
#define IE_CORE_RGBTOXYZCOLORTRANSFORM_INL

#include <cassert>

#include "OpenEXR/ImathVec.h"

#include "IECore/Convert.h"
#include "IECore/VectorTraits.h"

#include "IECore/XYZToRGBColorTransform.h"
#include "IECore/XYYToXYZColorTransform.h"

namespace IECore
{

template<typename F, typename T>
RGBToXYZColorTransform<F, T>::RGBToXYZColorTransform()
{
	setMatrix(
		Imath::V2f( 0.64, 0.33 ),
		Imath::V2f( 0.3, 0.6 ),
		Imath::V2f( 0.15, 0.06 ),
		Imath::V2f( 0.312713, 0.329016 )

	);
}

template<typename F, typename T>
template<typename M>
RGBToXYZColorTransform<F, T>::RGBToXYZColorTransform( const M &matrix )
{
	m_matrix = convert<Imath::M33f>( matrix );
}

template<typename F, typename T>
template<typename C>
RGBToXYZColorTransform<F, T>::RGBToXYZColorTransform(
	const C &rChromacity,
	const C &gChromacity,
	const C &bChromacity,

	const C &referenceWhite
)
{
	setMatrix( rChromacity, gChromacity, bChromacity, referenceWhite );
}

template<typename F, typename T>
template<typename C>
void RGBToXYZColorTransform<F, T>::setMatrix(
	const C &rChromacity,
	const C &gChromacity,
	const C &bChromacity,

	const C &referenceWhite
)
{
	BOOST_STATIC_ASSERT( ( TypeTraits::IsVec2<C>::value ) );

	typedef VectorTraits<C> VecTraits;

	XYYToXYZColorTransform< Imath::Color3f, Imath::Color3f > xyYToXYZ( referenceWhite );

	Imath::Color3f rXYZ = xyYToXYZ(
		Imath::Color3f(
			VecTraits::get( rChromacity, 0 ),
			VecTraits::get( rChromacity, 1 ),
			1.0
		)
	);

	Imath::Color3f gXYZ = xyYToXYZ(
		Imath::Color3f(
			VecTraits::get( gChromacity, 0 ),
			VecTraits::get( gChromacity, 1 ),
			1.0
		)
	);

	Imath::Color3f bXYZ = xyYToXYZ(
		Imath::Color3f(
			VecTraits::get( bChromacity, 0 ),
			VecTraits::get( bChromacity, 1 ),
			1.0
		)
	);

	Imath::Color3f wXYZ = xyYToXYZ(
		Imath::Color3f(
			VecTraits::get( referenceWhite, 0 ),
			VecTraits::get( referenceWhite, 1 ),
			1.0
		)
	);

	Imath::M33f m = Imath::M33f
		(
			rXYZ.x, rXYZ.y, rXYZ.z,
			gXYZ.x, gXYZ.y, gXYZ.z,
			bXYZ.x, bXYZ.y, bXYZ.z
		).inverse();

	Imath::V3f s = wXYZ * m;

	m_matrix = Imath::M33f
	(
		s.x * rXYZ.x, s.x * rXYZ.y, s.x * rXYZ.z,
		s.y * gXYZ.x, s.y * gXYZ.y, s.y * gXYZ.z,
		s.z * bXYZ.x, s.z * bXYZ.y, s.z * bXYZ.z
	);
}

template<typename F, typename T>
T RGBToXYZColorTransform<F, T>::operator()( F f )
{
	Imath::V3f from = IECore::convert< Imath::V3f >( f );

	return IECore::convert<T>( from * m_matrix );
}

template<typename F, typename T>
typename RGBToXYZColorTransform<F, T>::InverseType RGBToXYZColorTransform<F, T>::inverse() const
{
	return InverseType( m_matrix.inverse() );
}

template<typename F, typename T>
const Imath::M33f &RGBToXYZColorTransform<F, T>::matrix() const
{
	return m_matrix;
}

} // namespace IECore

#endif // IE_CORE_RGBTOXYZCOLORTRANSFORM_INL

<|endoftext|>


<commit_before>//  (C) Copyright Gennadiy Rozental 2001-2005.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : provides extention for unit test framework that allows usage
//  boost::function as a test case base function.
// ***************************************************************************

#ifndef BOOST_TEST_SUITE_EX_HPP_071894GER
#define BOOST_TEST_SUITE_EX_HPP_071894GER

// Boost.Test
#include <boost/test/unit_test_suite.hpp>
#include <boost/test/detail/workaround.hpp>

// Boost
#include <boost/function/function0.hpp>
#include <boost/function/function1.hpp>

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

namespace boost {

namespace unit_test {

// ************************************************************************** //
// **************            boost_function_test_case             ************** //
// ************************************************************************** //

class boost_function_test_case : public test_case {
public:
    typedef function0<void> function_type;

    // Constructor
    boost_function_test_case( function_type f_, const_string name_ )
    : test_case( name_, true, 1 ), m_function( f_ ) {}

protected:
    // test case implementation
    void                do_run()        { m_function(); }

private:
    // Data members
    function_type       m_function;
};

// ************************************************************************** //
// **************        parametrized_function_test_case       ************** //
// ************************************************************************** //

template <typename ParamIterator, typename ParameterType>
class parametrized_boost_function_test_case : public test_case {
public:
    typedef function1<void,ParameterType> function_type;

    // Constructor
    parametrized_boost_function_test_case( function_type f_, const_string name_,
                                        ParamIterator const& begin_, ParamIterator const& end_ )
    : test_case( name_, true, 0 ), m_first_parameter( begin_ ), m_last_parameter( end_ ), m_function( f_ )
    {
        p_stages_amount.set( ut_detail::distance( begin_, end_ ) );
    }

    // test case implementation
    void                do_init()       { m_curr_parameter = m_first_parameter; }
    void                do_run()        { m_function( *m_curr_parameter ); ++m_curr_parameter; }

private:
    // Data members
    ParamIterator       m_first_parameter;
    ParamIterator       m_last_parameter;
    ParamIterator       m_curr_parameter;

    function_type       m_function;
};

// ************************************************************************** //
// **************               object generators              ************** //
// ************************************************************************** //

inline test_case*
make_test_case( function0<void> const& fct_, const_string name_ )
{
    return new boost_function_test_case( fct_, ut_detail::normalize_test_case_name( name_ ) );
}

template<typename ParamIterator, typename ParameterType>
inline test_case*
make_test_case( function1<void,ParameterType> const& fct_, const_string name_,
                  ParamIterator const& begin_, ParamIterator const& end_ )
{
    return new parametrized_boost_function_test_case<ParamIterator,ParameterType>(
                    fct_, ut_detail::normalize_test_case_name( name_ ), begin_, end_ );
}

} // unit_test

} // namespace boost

//____________________________________________________________________________//

#include <boost/test/detail/enable_warnings.hpp>

// ***************************************************************************
//  Revision History :
//
//  $Log$
//  Revision 1.23  2005/02/22 01:33:13  vawjr
//  Corrected a spelling error on one of the includes
//
//  Revision 1.22  2005/02/20 08:27:06  rogeeff
//  This a major update for Boost.Test framework. See release docs for complete list of fixes/updates
//
//  Revision 1.21  2005/02/01 06:40:07  rogeeff
//  copyright update
//  old log entries removed
//  minor stilistic changes
//  depricated tools removed
//
//  Revision 1.20  2005/01/30 03:21:34  rogeeff
//  interface changed to use const_string
//
// ***************************************************************************

#endif // BOOST_TEST_SUITE_EX_HPP_071894GER
<commit_msg>no need anymore<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2014, 2015 Ben Deane
// This code is distributed under the MIT license. See LICENSE for details.

#include <complexity.h>

#include <algorithm>
#include <string>
using namespace std;

DEF_COMPLEXITY_PROPERTY(O_1, Complexity, ORDER_1, const string&, int)
{
}

char g_c;

DEF_COMPLEXITY_PROPERTY(O_LOG_N, Complexity, ORDER_LOG_N, const string& s)
{
  for (size_t i = 1, lim = s.size(); i < lim; i <<= 1)
  {
    g_c = s[i];
  }
}

DEF_COMPLEXITY_PROPERTY(O_N, Complexity, ORDER_N, const string& s)
{
  max_element(s.begin(), s.end());
}

DEF_COMPLEXITY_PROPERTY(O_N_LOG_N, Complexity, ORDER_N_LOG_N, const string& s)
{
  for (size_t i = 1, lim = s.size(); i < lim; i <<= 1)
  {
    max_element(s.begin(), s.end());
  }
}

DEF_COMPLEXITY_PROPERTY(ArrayCoverage, Complexity, ORDER_N2, const array<int, 10>&)
{
}
<commit_msg>Add test coverage for complexity of containers<commit_after>// Copyright (c) 2014, 2015 Ben Deane
// This code is distributed under the MIT license. See LICENSE for details.

#include <complexity.h>

#include <algorithm>
#include <string>
using namespace std;

DEF_COMPLEXITY_PROPERTY(O_1, Complexity, ORDER_1, const string&, int)
{
}

char g_c;

DEF_COMPLEXITY_PROPERTY(O_LOG_N, Complexity, ORDER_LOG_N, const string& s)
{
  for (size_t i = 1, lim = s.size(); i < lim; i <<= 1)
  {
    g_c = s[i];
  }
}

DEF_COMPLEXITY_PROPERTY(O_N, Complexity, ORDER_N, const string& s)
{
  max_element(s.begin(), s.end());
}

DEF_COMPLEXITY_PROPERTY(O_N_LOG_N, Complexity, ORDER_N_LOG_N, const string& s)
{
  for (size_t i = 1, lim = s.size(); i < lim; i <<= 1)
  {
    max_element(s.begin(), s.end());
  }
}

DEF_COMPLEXITY_PROPERTY(PairCoverage, Complexity, ORDER_N2, const pair<int, int>&)
{
}

DEF_COMPLEXITY_PROPERTY(VectorCoverage, Complexity, ORDER_N2, const vector<int>&)
{
}

DEF_COMPLEXITY_PROPERTY(DequeCoverage, Complexity, ORDER_N2, const deque<int>&)
{
}

DEF_COMPLEXITY_PROPERTY(ListCoverage, Complexity, ORDER_N2, const list<int>&)
{
}

DEF_COMPLEXITY_PROPERTY(ForwardListCoverage, Complexity, ORDER_N2, const forward_list<int>&)
{
}

DEF_COMPLEXITY_PROPERTY(ArrayCoverage, Complexity, ORDER_N2, const array<int, 10>&)
{
}

struct MyUnspecializedType {};

DEF_COMPLEXITY_PROPERTY(ArbitraryCoverage, Complexity, ORDER_N2, const MyUnspecializedType)
{
}
<|endoftext|>