<commit_before>#ifdef ENABLE_HIP

#include "hoomd/ExecutionConfiguration.h"

#include <stdio.h>
#include <string>
#include <vector>

#include "GPUEvalFactory.h"

// pybind11 vector bindings
#include <pybind11/pybind11.h>
#include <pybind11/stl_bind.h>

#include <hip/hip_runtime.h>

#if __HIP_PLATFORM_NVCC__
#include <cuda.h>
#include <nvrtc.h>

#include "jitify_safe_headers.hpp"

void GPUEvalFactory::compileGPU(
    const std::string& code,
    const std::string& kernel_name,
    const std::string& include_path,
    const std::string& include_path_source,
    const std::string& cuda_devrt_library_path,
    const unsigned int compute_arch)
    {
    m_exec_conf->msg->notice(3) << "Compiling nvrtc code" << std::endl;

    std::vector<std::string> compile_options = {
        "--gpu-architecture=compute_"+std::to_string(compute_arch),
        "--include-path="+include_path,
        "--include-path="+include_path_source,
        "--relocatable-device-code=true",
        "--device-as-default-execution-space",
        "--std=c++11",
#ifdef ENABLE_HPMC_MIXED_PRECISION
        "-DENABLE_HPMC_MIXED_PRECISION",
#endif
        "-DHOOMD_LLVMJIT_BUILD",
        "-D__HIPCC__",
        "-D__HIP_DEVICE_COMPILE__",
        "-D__HIP_PLATFORM_NVCC__",
        "-lineinfo"
        };

    char *compileParams[compile_options.size()];
    for (unsigned int i = 0; i < compile_options.size(); ++i)
        {
        compileParams[i] = reinterpret_cast<char *>(
            malloc(sizeof(char) * (compile_options[i].length() + 1)));
        snprintf(compileParams[i], compile_options[i].length() + 1, "%s",
                 compile_options[i].c_str());
        }

    // compile

    // add fake math headers + printf
    std::string printf_include = std::string("#define FILE int\n") +
        std::string("int fflush ( FILE * stream );\n") +
        std::string("int fprintf ( FILE * stream, const char * format, ... );\n");

    std::string code_with_headers = std::string(jitify::detail::jitsafe_header_math) +
        std::string(jitify::detail::jitsafe_header_type_traits) +
        //std::string(jitify::detail::jitsafe_header_stdint_h) +
        + "#define uint8_t unsigned char\n" +
        + "#define uint32_t unsigned int\n" +
        + "#define uint64_t unsigned long long\n" +
        printf_include + code;

    m_exec_conf->msg->notice(4) << code_with_headers << std::endl;

    nvrtcResult status = nvrtcCreateProgram(&m_program, code_with_headers.c_str(), "evaluator.cu", 0, NULL, NULL);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcCreateProgram error: "+std::string(nvrtcGetErrorString(status)));

    m_exec_conf->msg->notice(3) << "nvrtc options (notice level 4 shows code):" << std::endl;
    for (unsigned int i = 0; i < compile_options.size(); ++i)
        {
        m_exec_conf->msg->notice(3) << " " << compileParams[i] << std::endl;
        }

    status = nvrtcAddNameExpression(m_program, kernel_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    std::string alpha_iso_name = "&alpha_iso";
    status = nvrtcAddNameExpression(m_program, alpha_iso_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    std::string alpha_union_name = "&alpha_union";
    status = nvrtcAddNameExpression(m_program, alpha_union_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    std::string rcut_name = "&jit::d_rcut_union";
    status = nvrtcAddNameExpression(m_program, rcut_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    std::string union_params_name = "&jit::d_union_params";
    status = nvrtcAddNameExpression(m_program, union_params_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    nvrtcResult compile_result = nvrtcCompileProgram(m_program, compile_options.size(), compileParams);
    for (unsigned int i = 0; i < compile_options.size(); ++i)
        {
        free(compileParams[i]);
        }

    // Obtain compilation log from the program.
    size_t logSize;
    status = nvrtcGetProgramLogSize(m_program, &logSize);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetProgramLogSize error: "+std::string(nvrtcGetErrorString(status)));

    char *log = new char[logSize];
    status = nvrtcGetProgramLog(m_program, log);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetProgramLog error: "+std::string(nvrtcGetErrorString(status)));
    m_exec_conf->msg->notice(3) << "nvrtc output" << std::endl << log << '\n';
    delete[] log;

    if (compile_result != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcCompileProgram error (set device.notice_level=3 to see full log): "+std::string(nvrtcGetErrorString(compile_result)));

    // fetch PTX
    size_t ptx_size;
    status = nvrtcGetPTXSize(m_program, &ptx_size);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetPTXSize error: "+std::string(nvrtcGetErrorString(status)));

    char ptx[ptx_size];
    status = nvrtcGetPTX(m_program, ptx);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetPTX error: "+std::string(nvrtcGetErrorString(status)));

    // look up mangled names
    char *kernel_name_mangled;
    status = nvrtcGetLoweredName(m_program, kernel_name.c_str(), const_cast<const char **>(&kernel_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    char *alpha_iso_name_mangled;
    status = nvrtcGetLoweredName(m_program, alpha_iso_name.c_str(), const_cast<const char **>(&alpha_iso_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    char *alpha_union_name_mangled;
    status = nvrtcGetLoweredName(m_program, alpha_union_name.c_str(), const_cast<const char **>(&alpha_union_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    char *rcut_name_mangled;
    status = nvrtcGetLoweredName(m_program, rcut_name.c_str(), const_cast<const char **>(&rcut_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    char *union_params_name_mangled;
    status = nvrtcGetLoweredName(m_program, union_params_name.c_str(), const_cast<const char **>(&union_params_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    // link PTX into cubin
    CUresult custatus;
    char *error;
    custatus = cuLinkCreate(0, 0, 0, &m_link_state);
    if (custatus != CUDA_SUCCESS)
        {
        cuGetErrorString(custatus, const_cast<const char **>(&error));
        throw std::runtime_error("cuLinkCreate: "+std::string(error));
        }

    custatus = cuLinkAddFile(m_link_state, CU_JIT_INPUT_LIBRARY, cuda_devrt_library_path.c_str(), 0, 0, 0);
    if (custatus != CUDA_SUCCESS)
        {
        cuGetErrorString(custatus, const_cast<const char **>(&error));
        throw std::runtime_error("cuLinkAddFile: "+std::string(error));
        }

    custatus = cuLinkAddData(m_link_state, CU_JIT_INPUT_PTX, (void *) ptx, ptx_size, "evaluator.ptx", 0, 0, 0);
    if (custatus != CUDA_SUCCESS)
        {
        cuGetErrorString(custatus, const_cast<const char **>(&error));
        throw std::runtime_error("cuLinkAddData: "+std::string(error));
        }

    size_t cubinSize;
    void *cubin;

    custatus = cuLinkComplete(m_link_state, &cubin, &cubinSize);
    if (custatus != CUDA_SUCCESS)
        {
        cuGetErrorString(custatus, const_cast<const char **>(&error));
        throw std::runtime_error("cuLinkComplete: "+std::string(error));
        }

    // load cubin into active contexts, and return function pointers
    auto gpu_map = m_exec_conf->getGPUIds();
    m_module.resize(m_exec_conf->getNumActiveGPUs());
    for (int idev = m_exec_conf->getNumActiveGPUs()-1; idev >= 0; --idev)
        {
        cudaSetDevice(gpu_map[idev]);

        // get module
        custatus = cuModuleLoadData(&m_module[idev], cubin);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleLoadData: "+std::string(error));
            }

        // get variable pointers
        CUfunction kernel_ptr;
        custatus = cuModuleGetFunction(&kernel_ptr, m_module[idev], kernel_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetFunction: "+std::string(error));
            }
        m_kernel_ptr[idev] = kernel_ptr;

        // get variable pointers
        CUdeviceptr alpha_iso_ptr;
        custatus = cuModuleGetGlobal(&alpha_iso_ptr, 0, m_module[idev], alpha_iso_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetGlobal: "+std::string(error));
            }

        m_alpha_iso_device_ptr[idev] = alpha_iso_ptr;

        CUdeviceptr alpha_union_ptr;
        custatus = cuModuleGetGlobal(&alpha_union_ptr, 0, m_module[idev], alpha_union_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetGlobal: "+std::string(error));
            }
        m_alpha_union_device_ptr[idev] = alpha_union_ptr;

        CUdeviceptr rcut_ptr;
        custatus = cuModuleGetGlobal(&rcut_ptr, 0, m_module[idev], rcut_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetGlobal: "+std::string(error));
            }
        m_rcut_union_device_ptr[idev] = rcut_ptr;

        CUdeviceptr union_params_ptr;
        custatus = cuModuleGetGlobal(&union_params_ptr, 0, m_module[idev], union_params_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetGlobal: "+std::string(error));
            }
        m_union_params_device_ptr[idev] = union_params_ptr;
        }
    }
#endif
#endif
<commit_msg>clean up JIT includes a bit<commit_after>#ifdef ENABLE_HIP

#include "hoomd/ExecutionConfiguration.h"

#include <stdio.h>
#include <string>
#include <vector>

#include "GPUEvalFactory.h"

// pybind11 vector bindings
#include <pybind11/pybind11.h>
#include <pybind11/stl_bind.h>

#include <hip/hip_runtime.h>

#if __HIP_PLATFORM_NVCC__
#include <cuda.h>
#include <nvrtc.h>

#include "jitify_safe_headers.hpp"

void GPUEvalFactory::compileGPU(
    const std::string& code,
    const std::string& kernel_name,
    const std::string& include_path,
    const std::string& include_path_source,
    const std::string& cuda_devrt_library_path,
    const unsigned int compute_arch)
    {
    m_exec_conf->msg->notice(3) << "Compiling nvrtc code" << std::endl;

    std::vector<std::string> compile_options = {
        "--gpu-architecture=compute_"+std::to_string(compute_arch),
        "--include-path="+include_path,
        "--include-path="+include_path_source,
        "--relocatable-device-code=true",
        "--device-as-default-execution-space",
        "--std=c++11",
#ifdef ENABLE_HPMC_MIXED_PRECISION
        "-DENABLE_HPMC_MIXED_PRECISION",
#endif
        "-DHOOMD_LLVMJIT_BUILD",
        "-D__HIPCC__",
        "-D__HIP_DEVICE_COMPILE__",
        "-D__HIP_PLATFORM_NVCC__",
        "-lineinfo"
        };

    char *compileParams[compile_options.size()];
    for (unsigned int i = 0; i < compile_options.size(); ++i)
        {
        compileParams[i] = reinterpret_cast<char *>(
            malloc(sizeof(char) * (compile_options[i].length() + 1)));
        snprintf(compileParams[i], compile_options[i].length() + 1, "%s",
                 compile_options[i].c_str());
        }

    // compile

    // add fake math headers + printf + ..

    // these hacky includes exist primarily to enable use of some HOOMD
    // header files inside RTC
    std::string printf_include = std::string("#define FILE int\n") +
        std::string("int fflush ( FILE * stream );\n") +
        std::string("int fprintf ( FILE * stream, const char * format, ... );\n");

    std::string code_with_headers = std::string(jitify::detail::jitsafe_header_math) +
        std::string(jitify::detail::jitsafe_header_type_traits) +
        std::string(jitify::detail::jitsafe_header_stdint_h) +
        printf_include + code;

    m_exec_conf->msg->notice(4) << code_with_headers << std::endl;

    nvrtcResult status = nvrtcCreateProgram(&m_program, code_with_headers.c_str(), "evaluator.cu", 0, NULL, NULL);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcCreateProgram error: "+std::string(nvrtcGetErrorString(status)));

    m_exec_conf->msg->notice(3) << "nvrtc options (notice level 4 shows code):" << std::endl;
    for (unsigned int i = 0; i < compile_options.size(); ++i)
        {
        m_exec_conf->msg->notice(3) << " " << compileParams[i] << std::endl;
        }

    status = nvrtcAddNameExpression(m_program, kernel_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    std::string alpha_iso_name = "&alpha_iso";
    status = nvrtcAddNameExpression(m_program, alpha_iso_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    std::string alpha_union_name = "&alpha_union";
    status = nvrtcAddNameExpression(m_program, alpha_union_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    std::string rcut_name = "&jit::d_rcut_union";
    status = nvrtcAddNameExpression(m_program, rcut_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    std::string union_params_name = "&jit::d_union_params";
    status = nvrtcAddNameExpression(m_program, union_params_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    nvrtcResult compile_result = nvrtcCompileProgram(m_program, compile_options.size(), compileParams);
    for (unsigned int i = 0; i < compile_options.size(); ++i)
        {
        free(compileParams[i]);
        }

    // Obtain compilation log from the program.
    size_t logSize;
    status = nvrtcGetProgramLogSize(m_program, &logSize);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetProgramLogSize error: "+std::string(nvrtcGetErrorString(status)));

    char *log = new char[logSize];
    status = nvrtcGetProgramLog(m_program, log);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetProgramLog error: "+std::string(nvrtcGetErrorString(status)));
    m_exec_conf->msg->notice(3) << "nvrtc output" << std::endl << log << '\n';
    delete[] log;

    if (compile_result != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcCompileProgram error (set device.notice_level=3 to see full log): "+std::string(nvrtcGetErrorString(compile_result)));

    // fetch PTX
    size_t ptx_size;
    status = nvrtcGetPTXSize(m_program, &ptx_size);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetPTXSize error: "+std::string(nvrtcGetErrorString(status)));

    char ptx[ptx_size];
    status = nvrtcGetPTX(m_program, ptx);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetPTX error: "+std::string(nvrtcGetErrorString(status)));

    // look up mangled names
    char *kernel_name_mangled;
    status = nvrtcGetLoweredName(m_program, kernel_name.c_str(), const_cast<const char **>(&kernel_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    char *alpha_iso_name_mangled;
    status = nvrtcGetLoweredName(m_program, alpha_iso_name.c_str(), const_cast<const char **>(&alpha_iso_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    char *alpha_union_name_mangled;
    status = nvrtcGetLoweredName(m_program, alpha_union_name.c_str(), const_cast<const char **>(&alpha_union_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    char *rcut_name_mangled;
    status = nvrtcGetLoweredName(m_program, rcut_name.c_str(), const_cast<const char **>(&rcut_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    char *union_params_name_mangled;
    status = nvrtcGetLoweredName(m_program, union_params_name.c_str(), const_cast<const char **>(&union_params_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    // link PTX into cubin
    CUresult custatus;
    char *error;
    custatus = cuLinkCreate(0, 0, 0, &m_link_state);
    if (custatus != CUDA_SUCCESS)
        {
        cuGetErrorString(custatus, const_cast<const char **>(&error));
        throw std::runtime_error("cuLinkCreate: "+std::string(error));
        }

    custatus = cuLinkAddFile(m_link_state, CU_JIT_INPUT_LIBRARY, cuda_devrt_library_path.c_str(), 0, 0, 0);
    if (custatus != CUDA_SUCCESS)
        {
        cuGetErrorString(custatus, const_cast<const char **>(&error));
        throw std::runtime_error("cuLinkAddFile: "+std::string(error));
        }

    custatus = cuLinkAddData(m_link_state, CU_JIT_INPUT_PTX, (void *) ptx, ptx_size, "evaluator.ptx", 0, 0, 0);
    if (custatus != CUDA_SUCCESS)
        {
        cuGetErrorString(custatus, const_cast<const char **>(&error));
        throw std::runtime_error("cuLinkAddData: "+std::string(error));
        }

    size_t cubinSize;
    void *cubin;

    custatus = cuLinkComplete(m_link_state, &cubin, &cubinSize);
    if (custatus != CUDA_SUCCESS)
        {
        cuGetErrorString(custatus, const_cast<const char **>(&error));
        throw std::runtime_error("cuLinkComplete: "+std::string(error));
        }

    // load cubin into active contexts, and return function pointers
    auto gpu_map = m_exec_conf->getGPUIds();
    m_module.resize(m_exec_conf->getNumActiveGPUs());
    for (int idev = m_exec_conf->getNumActiveGPUs()-1; idev >= 0; --idev)
        {
        cudaSetDevice(gpu_map[idev]);

        // get module
        custatus = cuModuleLoadData(&m_module[idev], cubin);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleLoadData: "+std::string(error));
            }

        // get variable pointers
        CUfunction kernel_ptr;
        custatus = cuModuleGetFunction(&kernel_ptr, m_module[idev], kernel_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetFunction: "+std::string(error));
            }
        m_kernel_ptr[idev] = kernel_ptr;

        // get variable pointers
        CUdeviceptr alpha_iso_ptr;
        custatus = cuModuleGetGlobal(&alpha_iso_ptr, 0, m_module[idev], alpha_iso_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetGlobal: "+std::string(error));
            }

        m_alpha_iso_device_ptr[idev] = alpha_iso_ptr;

        CUdeviceptr alpha_union_ptr;
        custatus = cuModuleGetGlobal(&alpha_union_ptr, 0, m_module[idev], alpha_union_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetGlobal: "+std::string(error));
            }
        m_alpha_union_device_ptr[idev] = alpha_union_ptr;

        CUdeviceptr rcut_ptr;
        custatus = cuModuleGetGlobal(&rcut_ptr, 0, m_module[idev], rcut_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetGlobal: "+std::string(error));
            }
        m_rcut_union_device_ptr[idev] = rcut_ptr;

        CUdeviceptr union_params_ptr;
        custatus = cuModuleGetGlobal(&union_params_ptr, 0, m_module[idev], union_params_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetGlobal: "+std::string(error));
            }
        m_union_params_device_ptr[idev] = union_params_ptr;
        }
    }
#endif
#endif
<|endoftext|>


<commit_before>// Copyright 2016 The Brave Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "brave/renderer/brave_content_renderer_client.h"

#include "atom/renderer/content_settings_manager.h"
#include "brave/renderer/printing/brave_print_web_view_helper_delegate.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/secure_origin_whitelist.h"
#include "chrome/renderer/chrome_render_frame_observer.h"
#include "chrome/renderer/chrome_render_thread_observer.h"
#include "chrome/renderer/chrome_render_view_observer.h"
#include "chrome/renderer/content_settings_observer.h"
#include "chrome/renderer/net/net_error_helper.h"
#include "chrome/renderer/pepper/pepper_helper.h"
#include "chrome/renderer/plugins/non_loadable_plugin_placeholder.h"
#include "chrome/renderer/plugins/plugin_uma.h"
#include "content/public/common/content_constants.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
#include "components/autofill/content/renderer/autofill_agent.h"
#include "components/autofill/content/renderer/password_autofill_agent.h"
#include "components/autofill/content/renderer/password_generation_agent.h"
#include "components/network_hints/renderer/prescient_networking_dispatcher.h"
#include "components/password_manager/content/renderer/credential_manager_client.h"
#include "components/plugins/renderer/plugin_placeholder.h"
#include "components/printing/renderer/print_web_view_helper.h"
#include "components/spellcheck/spellcheck_build_features.h"
#include "components/visitedlink/renderer/visitedlink_slave.h"
#include "components/web_cache/renderer/web_cache_impl.h"
#include "extensions/features/features.h"
#include "third_party/WebKit/public/platform/URLConversion.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebPlugin.h"
#include "third_party/WebKit/public/web/WebPluginParams.h"
#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
#if defined(OS_WIN)
#include <shlobj.h>
#include "base/command_line.h"
#include "atom/common/options_switches.h"
#endif

#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/renderer/extensions/chrome_extensions_renderer_client.h"
#endif

#if BUILDFLAG(ENABLE_SPELLCHECK)
#include "components/spellcheck/renderer/spellcheck.h"
#include "components/spellcheck/renderer/spellcheck_provider.h"

#if BUILDFLAG(HAS_SPELLCHECK_PANEL)
#include "components/spellcheck/renderer/spellcheck_panel.h"
#endif  // BUILDFLAG(HAS_SPELLCHECK_PANEL)
#endif

using autofill::AutofillAgent;
using autofill::PasswordAutofillAgent;
using autofill::PasswordGenerationAgent;
using blink::WebLocalFrame;
using blink::WebPlugin;
using blink::WebPluginParams;
using blink::WebSecurityOrigin;
using blink::WebSecurityPolicy;
using blink::WebString;

namespace brave {

BraveContentRendererClient::BraveContentRendererClient() {
}

void BraveContentRendererClient::RenderThreadStarted() {
  content::RenderThread* thread = content::RenderThread::Get();

  content_settings_manager_ = atom::ContentSettingsManager::GetInstance();
  #if defined(OS_WIN)
    // Set ApplicationUserModelID in renderer process.
    base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
    base::string16 app_id =
        command_line->GetSwitchValueNative(atom::switches::kAppUserModelId);
    if (!app_id.empty()) {
      SetCurrentProcessExplicitAppUserModelID(app_id.c_str());
    }
  #endif

  chrome_observer_.reset(new ChromeRenderThreadObserver());
  web_cache_impl_.reset(new web_cache::WebCacheImpl());

#if BUILDFLAG(ENABLE_EXTENSIONS)
  ChromeExtensionsRendererClient::GetInstance()->RenderThreadStarted();
#endif

  thread->AddObserver(chrome_observer_.get());

  prescient_networking_dispatcher_.reset(
      new network_hints::PrescientNetworkingDispatcher());

  for (auto& origin : GetSecureOriginWhitelist()) {
    WebSecurityPolicy::AddOriginTrustworthyWhiteList(
        WebSecurityOrigin::Create(origin));
  }

  for (auto& scheme : GetSchemesBypassingSecureContextCheckWhitelist()) {
    WebSecurityPolicy::AddSchemeToBypassSecureContextWhitelist(
        WebString::FromUTF8(scheme));
  }

#if BUILDFLAG(ENABLE_SPELLCHECK)
  if (!spellcheck_) {
    spellcheck_.reset(new SpellCheck());
    thread->AddObserver(spellcheck_.get());
  }
#endif
}

unsigned long long BraveContentRendererClient::VisitedLinkHash(  // NOLINT
    const char* canonical_url, size_t length) {
  return chrome_observer_->visited_link_slave()->ComputeURLFingerprint(
      canonical_url, length);
}

bool BraveContentRendererClient::IsLinkVisited(unsigned long long link_hash) {  // NOLINT
  return chrome_observer_->visited_link_slave()->IsVisited(link_hash);
}

blink::WebPrescientNetworking*
BraveContentRendererClient::GetPrescientNetworking() {
  return prescient_networking_dispatcher_.get();
}

void BraveContentRendererClient::RenderFrameCreated(
    content::RenderFrame* render_frame) {
  bool should_whitelist_for_content_settings = false;
  extensions::Dispatcher* ext_dispatcher = NULL;
#if BUILDFLAG(ENABLE_EXTENSIONS)
  ext_dispatcher =
      ChromeExtensionsRendererClient::GetInstance()->extension_dispatcher();
#endif
  ContentSettingsObserver* content_settings = new ContentSettingsObserver(
      render_frame, ext_dispatcher, should_whitelist_for_content_settings);
  if (chrome_observer_.get()) {
    content_settings->SetContentSettingRules(
        chrome_observer_->content_setting_rules());
  }

  if (content_settings_manager_) {
    content_settings->SetContentSettingsManager(content_settings_manager_);
  }

#if BUILDFLAG(ENABLE_EXTENSIONS)
  ChromeExtensionsRendererClient::GetInstance()->RenderFrameCreated(
      render_frame);
#endif

#if BUILDFLAG(ENABLE_PLUGINS)
  new PepperHelper(render_frame);
#endif

  new NetErrorHelper(render_frame);

  PasswordAutofillAgent* password_autofill_agent =
      new PasswordAutofillAgent(render_frame);
  PasswordGenerationAgent* password_generation_agent =
      new PasswordGenerationAgent(render_frame, password_autofill_agent);
  new AutofillAgent(render_frame, password_autofill_agent,
                    password_generation_agent);
#if BUILDFLAG(ENABLE_PRINTING)
  new printing::PrintWebViewHelper(
      render_frame, base::MakeUnique<BravePrintWebViewHelperDelegate>());
#endif

#if BUILDFLAG(ENABLE_SPELLCHECK)
  new SpellCheckProvider(render_frame, spellcheck_.get());
#endif
}

void BraveContentRendererClient::RenderViewCreated(
    content::RenderView* render_view) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
  ChromeExtensionsRendererClient::GetInstance()->RenderViewCreated(render_view);
#endif
  new ChromeRenderViewObserver(render_view, web_cache_impl_.get());

  new password_manager::CredentialManagerClient(render_view);

#if BUILDFLAG(ENABLE_SPELLCHECK)
  // This is a workaround keeping the behavior that, the Blink side spellcheck
  // enabled state is initialized on RenderView creation.
  // TODO(xiaochengh): Design better way to sync between Chrome-side and
  // Blink-side spellcheck enabled states.  See crbug.com/710097.
  if (SpellCheckProvider* provider =
          SpellCheckProvider::Get(render_view->GetMainRenderFrame()))
    provider->EnableSpellcheck(spellcheck_->IsSpellcheckEnabled());
#if BUILDFLAG(HAS_SPELLCHECK_PANEL)
  new SpellCheckPanel(render_view);
#endif  // BUILDFLAG(HAS_SPELLCHECK_PANEL)
#endif
}

bool BraveContentRendererClient::OverrideCreatePlugin(
    content::RenderFrame* render_frame,
    const WebPluginParams& params,
    WebPlugin** plugin) {
  std::string orig_mime_type = params.mime_type.Utf8();
  if (orig_mime_type == content::kBrowserPluginMimeType)
    return false;

  GURL url(params.url);
#if BUILDFLAG(ENABLE_PLUGINS)
  ChromeViewHostMsg_GetPluginInfo_Output output;
  render_frame->Send(new ChromeViewHostMsg_GetPluginInfo(
      render_frame->GetRoutingID(), url,
      render_frame->GetWebFrame()->Top()->GetSecurityOrigin(), orig_mime_type,
      &output));

  *plugin = CreatePlugin(render_frame, params, output);
#else  // !BUILDFLAG(ENABLE_PLUGINS)
  PluginUMAReporter::GetInstance()->ReportPluginMissing(orig_mime_type, url);
  *plugin = NonLoadablePluginPlaceholder::CreateNotSupportedPlugin(
                render_frame, render_frame->GetWebFrame(), params)
                ->plugin();
#endif  // BUILDFLAG(ENABLE_PLUGINS)
  return true;
}

}  // namespace brave
<commit_msg>Update SpellCheckPanel parameter<commit_after>// Copyright 2016 The Brave Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "brave/renderer/brave_content_renderer_client.h"

#include "atom/renderer/content_settings_manager.h"
#include "brave/renderer/printing/brave_print_web_view_helper_delegate.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/secure_origin_whitelist.h"
#include "chrome/renderer/chrome_render_frame_observer.h"
#include "chrome/renderer/chrome_render_thread_observer.h"
#include "chrome/renderer/chrome_render_view_observer.h"
#include "chrome/renderer/content_settings_observer.h"
#include "chrome/renderer/net/net_error_helper.h"
#include "chrome/renderer/pepper/pepper_helper.h"
#include "chrome/renderer/plugins/non_loadable_plugin_placeholder.h"
#include "chrome/renderer/plugins/plugin_uma.h"
#include "content/public/common/content_constants.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
#include "components/autofill/content/renderer/autofill_agent.h"
#include "components/autofill/content/renderer/password_autofill_agent.h"
#include "components/autofill/content/renderer/password_generation_agent.h"
#include "components/network_hints/renderer/prescient_networking_dispatcher.h"
#include "components/password_manager/content/renderer/credential_manager_client.h"
#include "components/plugins/renderer/plugin_placeholder.h"
#include "components/printing/renderer/print_web_view_helper.h"
#include "components/spellcheck/spellcheck_build_features.h"
#include "components/visitedlink/renderer/visitedlink_slave.h"
#include "components/web_cache/renderer/web_cache_impl.h"
#include "extensions/features/features.h"
#include "third_party/WebKit/public/platform/URLConversion.h"
#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebPlugin.h"
#include "third_party/WebKit/public/web/WebPluginParams.h"
#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
#if defined(OS_WIN)
#include <shlobj.h>
#include "base/command_line.h"
#include "atom/common/options_switches.h"
#endif

#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/renderer/extensions/chrome_extensions_renderer_client.h"
#endif

#if BUILDFLAG(ENABLE_SPELLCHECK)
#include "components/spellcheck/renderer/spellcheck.h"
#include "components/spellcheck/renderer/spellcheck_provider.h"

#if BUILDFLAG(HAS_SPELLCHECK_PANEL)
#include "components/spellcheck/renderer/spellcheck_panel.h"
#endif  // BUILDFLAG(HAS_SPELLCHECK_PANEL)
#endif

using autofill::AutofillAgent;
using autofill::PasswordAutofillAgent;
using autofill::PasswordGenerationAgent;
using blink::WebLocalFrame;
using blink::WebPlugin;
using blink::WebPluginParams;
using blink::WebSecurityOrigin;
using blink::WebSecurityPolicy;
using blink::WebString;

namespace brave {

BraveContentRendererClient::BraveContentRendererClient() {
}

void BraveContentRendererClient::RenderThreadStarted() {
  content::RenderThread* thread = content::RenderThread::Get();

  content_settings_manager_ = atom::ContentSettingsManager::GetInstance();
  #if defined(OS_WIN)
    // Set ApplicationUserModelID in renderer process.
    base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
    base::string16 app_id =
        command_line->GetSwitchValueNative(atom::switches::kAppUserModelId);
    if (!app_id.empty()) {
      SetCurrentProcessExplicitAppUserModelID(app_id.c_str());
    }
  #endif

  chrome_observer_.reset(new ChromeRenderThreadObserver());
  web_cache_impl_.reset(new web_cache::WebCacheImpl());

#if BUILDFLAG(ENABLE_EXTENSIONS)
  ChromeExtensionsRendererClient::GetInstance()->RenderThreadStarted();
#endif

  thread->AddObserver(chrome_observer_.get());

  prescient_networking_dispatcher_.reset(
      new network_hints::PrescientNetworkingDispatcher());

  for (auto& origin : GetSecureOriginWhitelist()) {
    WebSecurityPolicy::AddOriginTrustworthyWhiteList(
        WebSecurityOrigin::Create(origin));
  }

  for (auto& scheme : GetSchemesBypassingSecureContextCheckWhitelist()) {
    WebSecurityPolicy::AddSchemeToBypassSecureContextWhitelist(
        WebString::FromUTF8(scheme));
  }

#if BUILDFLAG(ENABLE_SPELLCHECK)
  if (!spellcheck_) {
    spellcheck_.reset(new SpellCheck());
    thread->AddObserver(spellcheck_.get());
  }
#endif
}

unsigned long long BraveContentRendererClient::VisitedLinkHash(  // NOLINT
    const char* canonical_url, size_t length) {
  return chrome_observer_->visited_link_slave()->ComputeURLFingerprint(
      canonical_url, length);
}

bool BraveContentRendererClient::IsLinkVisited(unsigned long long link_hash) {  // NOLINT
  return chrome_observer_->visited_link_slave()->IsVisited(link_hash);
}

blink::WebPrescientNetworking*
BraveContentRendererClient::GetPrescientNetworking() {
  return prescient_networking_dispatcher_.get();
}

void BraveContentRendererClient::RenderFrameCreated(
    content::RenderFrame* render_frame) {
  bool should_whitelist_for_content_settings = false;
  extensions::Dispatcher* ext_dispatcher = NULL;
#if BUILDFLAG(ENABLE_EXTENSIONS)
  ext_dispatcher =
      ChromeExtensionsRendererClient::GetInstance()->extension_dispatcher();
#endif
  ContentSettingsObserver* content_settings = new ContentSettingsObserver(
      render_frame, ext_dispatcher, should_whitelist_for_content_settings);
  if (chrome_observer_.get()) {
    content_settings->SetContentSettingRules(
        chrome_observer_->content_setting_rules());
  }

  if (content_settings_manager_) {
    content_settings->SetContentSettingsManager(content_settings_manager_);
  }

#if BUILDFLAG(ENABLE_EXTENSIONS)
  ChromeExtensionsRendererClient::GetInstance()->RenderFrameCreated(
      render_frame);
#endif

#if BUILDFLAG(ENABLE_PLUGINS)
  new PepperHelper(render_frame);
#endif

  new NetErrorHelper(render_frame);

  PasswordAutofillAgent* password_autofill_agent =
      new PasswordAutofillAgent(render_frame);
  PasswordGenerationAgent* password_generation_agent =
      new PasswordGenerationAgent(render_frame, password_autofill_agent);
  new AutofillAgent(render_frame, password_autofill_agent,
                    password_generation_agent);
#if BUILDFLAG(ENABLE_PRINTING)
  new printing::PrintWebViewHelper(
      render_frame, base::MakeUnique<BravePrintWebViewHelperDelegate>());
#endif

#if BUILDFLAG(ENABLE_SPELLCHECK)
  new SpellCheckProvider(render_frame, spellcheck_.get());
#if BUILDFLAG(HAS_SPELLCHECK_PANEL)
  new SpellCheckPanel(render_frame);
#endif  // BUILDFLAG(HAS_SPELLCHECK_PANEL)
#endif
}

void BraveContentRendererClient::RenderViewCreated(
    content::RenderView* render_view) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
  ChromeExtensionsRendererClient::GetInstance()->RenderViewCreated(render_view);
#endif
  new ChromeRenderViewObserver(render_view, web_cache_impl_.get());

  new password_manager::CredentialManagerClient(render_view);

#if BUILDFLAG(ENABLE_SPELLCHECK)
  // This is a workaround keeping the behavior that, the Blink side spellcheck
  // enabled state is initialized on RenderView creation.
  // TODO(xiaochengh): Design better way to sync between Chrome-side and
  // Blink-side spellcheck enabled states.  See crbug.com/710097.
  if (SpellCheckProvider* provider =
          SpellCheckProvider::Get(render_view->GetMainRenderFrame()))
    provider->EnableSpellcheck(spellcheck_->IsSpellcheckEnabled());
#endif
}

bool BraveContentRendererClient::OverrideCreatePlugin(
    content::RenderFrame* render_frame,
    const WebPluginParams& params,
    WebPlugin** plugin) {
  std::string orig_mime_type = params.mime_type.Utf8();
  if (orig_mime_type == content::kBrowserPluginMimeType)
    return false;

  GURL url(params.url);
#if BUILDFLAG(ENABLE_PLUGINS)
  ChromeViewHostMsg_GetPluginInfo_Output output;
  render_frame->Send(new ChromeViewHostMsg_GetPluginInfo(
      render_frame->GetRoutingID(), url,
      render_frame->GetWebFrame()->Top()->GetSecurityOrigin(), orig_mime_type,
      &output));

  *plugin = CreatePlugin(render_frame, params, output);
#else  // !BUILDFLAG(ENABLE_PLUGINS)
  PluginUMAReporter::GetInstance()->ReportPluginMissing(orig_mime_type, url);
  *plugin = NonLoadablePluginPlaceholder::CreateNotSupportedPlugin(
                render_frame, render_frame->GetWebFrame(), params)
                ->plugin();
#endif  // BUILDFLAG(ENABLE_PLUGINS)
  return true;
}

}  // namespace brave
<|endoftext|>


<commit_before>/*******************************************************************************
 * thrill/mem/allocator.hpp
 *
 * Part of Project Thrill.
 *
 * Copyright (C) 2015 Timo Bingmann <tb@panthema.net>
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef THRILL_MEM_ALLOCATOR_HEADER
#define THRILL_MEM_ALLOCATOR_HEADER

#include <thrill/mem/allocator_base.hpp>
#include <thrill/mem/manager.hpp>

#include <cassert>
#include <deque>
#include <iosfwd>
#include <memory>
#include <new>
#include <string>
#include <type_traits>
#include <vector>

namespace thrill {
namespace mem {

template <typename Type>
class Allocator : public AllocatorBase<Type>
{
    static const bool debug = false;

public:
    using value_type = Type;
    using pointer = Type *;
    using const_pointer = const Type *;
    using reference = Type &;
    using const_reference = const Type &;
    using size_type = std::size_t;
    using difference_type = std::ptrdiff_t;

    //! C++11 type flag
    using is_always_equal = std::false_type;

    //! Return allocator for different type.
    template <class U>
    struct rebind { using other = Allocator<U>; };

    //! Construct Allocator with Manager object
    explicit Allocator(Manager& manager) noexcept
        : manager_(&manager) { }

    //! copy-constructor
    Allocator(const Allocator&) noexcept = default;

    //! copy-constructor from a rebound allocator
    template <typename OtherType>
    Allocator(const Allocator<OtherType>& other) noexcept
        : manager_(other.manager_) { }

    //! Attempts to allocate a block of storage with a size large enough to
    //! contain n elements of member type value_type, and returns a pointer to
    //! the first element.
    pointer allocate(size_type n, const void* /* hint */ = nullptr) {
        if (n > this->max_size())
            throw std::bad_alloc();

        manager_->add(n * sizeof(Type));

        if (debug) {
            printf("allocate() n=%lu sizeof(T)=%lu total=%lu\n",
                   n, sizeof(Type), manager_->total());
        }

        return static_cast<Type*>(bypass_malloc(n * sizeof(Type)));
    }

    //! Releases a block of storage previously allocated with member allocate
    //! and not yet released.
    void deallocate(pointer p, size_type n) const noexcept {

        manager_->subtract(n * sizeof(Type));

        if (debug) {
            printf("deallocate() n=%lu sizeof(T)=%lu total=%lu\n",
                   n, sizeof(Type), manager_->total());
        }

        bypass_free(p);
    }

    //! pointer to common Manager object. If we use a reference here, then
    //! the allocator cannot be default move/assigned anymore.
    Manager* manager_;

    //! Compare to another allocator of same type
    template <class Other>
    bool operator == (const Allocator<Other>& other) const noexcept {
        return (manager_ == other.manager_);
    }

    //! Compare to another allocator of same type
    template <class Other>
    bool operator != (const Allocator<Other>& other) const noexcept {
        return (manager_ != other.manager_);
    }
};

//! operator new with our Allocator
template <typename T, class ... Args>
T * mm_new(Manager& manager, Args&& ... args) {
    Allocator<T> allocator(manager);
    T* value = allocator.allocate(1);
    allocator.construct(value, std::forward<Args>(args) ...);
    return value;
}

//! operator delete with our Allocator
template <typename T>
void mm_delete(Manager& manager, T* value) {
    Allocator<T> allocator(manager);
    allocator.destroy(value);
    allocator.deallocate(value, 1);
}

//! std::default_deleter with Manager tracking
template <typename T>
class Deleter
{
public:
    //! constructor: need reference to Manager
    explicit Deleter(Manager& manager) noexcept
        : allocator_(manager) { }

    //! free the pointer
    void operator () (T* ptr) const noexcept {
        allocator_.destroy(ptr);
        allocator_.deallocate(ptr, 1);
    }

protected:
    //! reference to Manager for freeing.
    Allocator<T> allocator_;
};

//! unique_ptr with Manager tracking
template <typename T>
using mm_unique_ptr = std::unique_ptr<T, Deleter<T> >;

//! make_unique with Manager tracking
template <typename T, class ... Args>
mm_unique_ptr<T> mm_make_unique(Manager& manager, Args&& ... args) {
    return mm_unique_ptr<T>(
        mm_new<T>(manager, std::forward<Args>(args) ...),
        Deleter<T>(manager));
}

//! string with Manager tracking
using mm_string = std::basic_string<
          char, std::char_traits<char>, Allocator<char> >;

//! stringbuf with Manager tracking
using mm_stringbuf = std::basic_stringbuf<
          char, std::char_traits<char>, Allocator<char> >;

//! vector with Manager tracking
template <typename T>
using mm_vector = std::vector<T, Allocator<T> >;

//! deque with Manager tracking
template <typename T>
using mm_deque = std::deque<T, Allocator<T> >;

} // namespace mem
} // namespace thrill

#endif // !THRILL_MEM_ALLOCATOR_HEADER

/******************************************************************************/
<commit_msg>Adding mem::Allocator<void><commit_after>/*******************************************************************************
 * thrill/mem/allocator.hpp
 *
 * Part of Project Thrill.
 *
 * Copyright (C) 2015 Timo Bingmann <tb@panthema.net>
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef THRILL_MEM_ALLOCATOR_HEADER
#define THRILL_MEM_ALLOCATOR_HEADER

#include <thrill/mem/allocator_base.hpp>
#include <thrill/mem/manager.hpp>

#include <cassert>
#include <deque>
#include <iosfwd>
#include <memory>
#include <new>
#include <string>
#include <type_traits>
#include <vector>

namespace thrill {
namespace mem {

template <typename Type>
class Allocator : public AllocatorBase<Type>
{
    static const bool debug = false;

public:
    using value_type = Type;
    using pointer = Type *;
    using const_pointer = const Type *;
    using reference = Type &;
    using const_reference = const Type &;
    using size_type = std::size_t;
    using difference_type = std::ptrdiff_t;

    //! C++11 type flag
    using is_always_equal = std::false_type;

    //! Return allocator for different type.
    template <class U>
    struct rebind { using other = Allocator<U>; };

    //! Construct Allocator with Manager object
    explicit Allocator(Manager& manager) noexcept
        : manager_(&manager) { }

    //! copy-constructor
    Allocator(const Allocator&) noexcept = default;

    //! copy-constructor from a rebound allocator
    template <typename OtherType>
    Allocator(const Allocator<OtherType>& other) noexcept
        : manager_(other.manager_) { }

    //! Attempts to allocate a block of storage with a size large enough to
    //! contain n elements of member type value_type, and returns a pointer to
    //! the first element.
    pointer allocate(size_type n, const void* /* hint */ = nullptr) {
        if (n > this->max_size())
            throw std::bad_alloc();

        manager_->add(n * sizeof(Type));

        if (debug) {
            printf("allocate() n=%lu sizeof(T)=%lu total=%lu\n",
                   n, sizeof(Type), manager_->total());
        }

        return static_cast<Type*>(bypass_malloc(n * sizeof(Type)));
    }

    //! Releases a block of storage previously allocated with member allocate
    //! and not yet released.
    void deallocate(pointer p, size_type n) const noexcept {

        manager_->subtract(n * sizeof(Type));

        if (debug) {
            printf("deallocate() n=%lu sizeof(T)=%lu total=%lu\n",
                   n, sizeof(Type), manager_->total());
        }

        bypass_free(p);
    }

    //! pointer to common Manager object. If we use a reference here, then
    //! the allocator cannot be default move/assigned anymore.
    Manager* manager_;

    //! Compare to another allocator of same type
    template <class Other>
    bool operator == (const Allocator<Other>& other) const noexcept {
        return (manager_ == other.manager_);
    }

    //! Compare to another allocator of same type
    template <class Other>
    bool operator != (const Allocator<Other>& other) const noexcept {
        return (manager_ != other.manager_);
    }
};

template <>
class Allocator<void>
{
public:
    using pointer = void*;
    using const_pointer = const void*;
    using value_type = void;

    //! C++11 type flag
    using is_always_equal = std::false_type;

    template <class U>
    struct rebind { using other = Allocator<U>; };

    //! Construct Allocator with Manager object
    explicit Allocator(Manager& manager) noexcept
        : manager_(&manager) { }

    //! copy-constructor
    Allocator(const Allocator&) noexcept = default;

    //! copy-constructor from a rebound allocator
    template <typename OtherType>
    Allocator(const Allocator<OtherType>& other) noexcept
        : manager_(other.manager_) { }

    //! pointer to common Manager object. If we use a reference here, then
    //! the allocator cannot be default move/assigned anymore.
    Manager* manager_;

    //! Compare to another allocator of same type
    template <class Other>
    bool operator == (const Allocator<Other>& other) const noexcept {
        return (manager_ == other.manager_);
    }

    //! Compare to another allocator of same type
    template <class Other>
    bool operator != (const Allocator<Other>& other) const noexcept {
        return (manager_ != other.manager_);
    }
};

//! operator new with our Allocator
template <typename T, class ... Args>
T * mm_new(Manager& manager, Args&& ... args) {
    Allocator<T> allocator(manager);
    T* value = allocator.allocate(1);
    allocator.construct(value, std::forward<Args>(args) ...);
    return value;
}

//! operator delete with our Allocator
template <typename T>
void mm_delete(Manager& manager, T* value) {
    Allocator<T> allocator(manager);
    allocator.destroy(value);
    allocator.deallocate(value, 1);
}

//! std::default_deleter with Manager tracking
template <typename T>
class Deleter
{
public:
    //! constructor: need reference to Manager
    explicit Deleter(Manager& manager) noexcept
        : allocator_(manager) { }

    //! free the pointer
    void operator () (T* ptr) const noexcept {
        allocator_.destroy(ptr);
        allocator_.deallocate(ptr, 1);
    }

protected:
    //! reference to Manager for freeing.
    Allocator<T> allocator_;
};

//! unique_ptr with Manager tracking
template <typename T>
using mm_unique_ptr = std::unique_ptr<T, Deleter<T> >;

//! make_unique with Manager tracking
template <typename T, class ... Args>
mm_unique_ptr<T> mm_make_unique(Manager& manager, Args&& ... args) {
    return mm_unique_ptr<T>(
        mm_new<T>(manager, std::forward<Args>(args) ...),
        Deleter<T>(manager));
}

//! string with Manager tracking
using mm_string = std::basic_string<
          char, std::char_traits<char>, Allocator<char> >;

//! stringbuf with Manager tracking
using mm_stringbuf = std::basic_stringbuf<
          char, std::char_traits<char>, Allocator<char> >;

//! vector with Manager tracking
template <typename T>
using mm_vector = std::vector<T, Allocator<T> >;

//! deque with Manager tracking
template <typename T>
using mm_deque = std::deque<T, Allocator<T> >;

} // namespace mem
} // namespace thrill

#endif // !THRILL_MEM_ALLOCATOR_HEADER

/******************************************************************************/
<|endoftext|>


<commit_before>/**
 * Name: Primality test
 * Author: Richard Hladik
 * Description: Deterministic Miller-Rabin primality test, works for $p \leq 2^{32}$.
 * Time: $O(\log p)$
 */
#include "fastexp.cpp"

bool isprime(ll p) {
	if (p == 2 || p == 7 || p == 61)
		return true;
	if (p < 2 || !(p % 2))
		return false;
	int cnt = 0;
	ll d = p - 1;
	while (d % 2 == 0)
		d /= 2, cnt++;
	/// It's been proven testing only these witnesses suffices for all p that
	/// concern us
	for (ll a: (vector<ll>){2, 7, 61}) {
		bool passed = false;
		ll ad = fastexp(a, d, p);
		passed |= ad == 1;
		for (int i = 0; i < cnt; i++, ad = (ad * ad) % p)
			passed |= ad == p - 1;
		if (!passed)
			return false;
	}
	return true;
}
<commit_msg>Add support for primes ≤ 1e18 in Miller–Rabin (#71)<commit_after>/**
 * Name: Primality test
 * Author: Richard Hladik
 * Description: Deterministic Miller-Rabin primality test, works for $p \leq 2^{32}$.
 * Time: $O(\log p)$
 */
#include "fastexp.cpp"

bool isprime(ll p) {
	vector<ll> wit = {2, 7, 61};
	// For p < 1e18, use 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37
	// plus KACTL mod_pow (which can multiply modulo m ≤ 1e18)
	if (count(wit.begin(), wit.end(), p))
		return true;
	if (p < 2 || !(p % 2))
		return false;
	int cnt = 0;
	ll d = p - 1;
	while (d % 2 == 0)
		d /= 2, cnt++;
	/// It's been proven testing only these witnesses suffices for all p that
	/// concern us
	for (ll a: wit) {
		bool passed = false;
		ll ad = fastexp(a, d, p);
		passed |= ad == 1;
		for (int i = 0; i < cnt; i++, ad = (ad * ad) % p)
			passed |= ad == p - 1;
		if (!passed)
			return false;
	}
	return true;
}
<|endoftext|>


<commit_before>#include "SkCGUtils.h"
#include "SkBitmap.h"

extern CGImageRef SkCreateCGImageRef(const SkBitmap&);

static void SkBitmap_ReleaseInfo(void* info, const void* pixelData, size_t size) {
    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info);
    delete bitmap;
}

static SkBitmap* prepareForImageRef(const SkBitmap& bm,
                                    size_t* bitsPerComponent,
                                    CGBitmapInfo* info) {
    switch (bm.config()) {
        case SkBitmap::kARGB_8888_Config:
            *bitsPerComponent = 8;
            // try to match our rgba ordering in SkColorPriv, but take into
            // account that the data layout could have been overridden in
            // SkUserConfig.
#define HAS_ARGB_SHIFTS(a, r, g, b) \
            (SK_A32_SHIFT == (a) && SK_R32_SHIFT == (r) \
             && SK_G32_SHIFT == (g) && SK_B32_SHIFT == (b))
#if defined(SK_CPU_LENDIAN) && HAS_ARGB_SHIFTS(24, 0, 8, 16) \
 || defined(SK_CPU_BENDIAN) && HAS_ARGB_SHIFTS(0, 24, 16, 8)
            // The default rgba ordering from SkColorPriv.h
            *info = kCGBitmapByteOrder32Big |
                    kCGImageAlphaPremultipliedLast;
#elif defined(SK_CPU_LENDIAN) && HAS_ARGB_SHIFTS(24, 16, 8, 0) \
   || defined(SK_CPU_BENDIAN) && HAS_ARGB_SHIFTS(24, 16, 8, 0)
            // Matches the CGBitmapInfo that Apple recommends for best
            // performance, used by google chrome.
            *info = kCGBitmapByteOrder32Host |
                    kCGImageAlphaPremultipliedFirst;
#else
// ...add more formats as required...
#warning Cannot convert SkBitmap to CGImageRef with these shiftmasks. \
            This will probably not work.
            // Legacy behavior. Perhaps turn this into an error at some
            // point.
            *info = kCGBitmapByteOrder32Big |
                    kCGImageAlphaPremultipliedLast;
#endif
#undef HAS_ARGB_SHIFTS
            break;
        case SkBitmap::kRGB_565_Config:
            // doesn't see quite right. Are they thinking 1555?
            *bitsPerComponent = 5;
            *info = kCGBitmapByteOrder16Little;
            break;
        case SkBitmap::kARGB_4444_Config:
            *bitsPerComponent = 4;
            *info = kCGBitmapByteOrder16Little | kCGImageAlphaPremultipliedLast;
            break;
        default:
            return NULL;
    }

    return new SkBitmap(bm);
}

CGImageRef SkCreateCGImageRef(const SkBitmap& bm) {
    size_t bitsPerComponent;
    CGBitmapInfo info;

    SkBitmap* bitmap = prepareForImageRef(bm, &bitsPerComponent, &info);
    if (NULL == bitmap) {
        return NULL;
    }

    const int w = bitmap->width();
    const int h = bitmap->height();
    const size_t s = bitmap->getSize();

    // our provider "owns" the bitmap*, and will take care of deleting it
	// we initially lock it, so we can access the pixels. The bitmap will be deleted in the release
	// proc, which will in turn unlock the pixels
	bitmap->lockPixels();
    CGDataProviderRef dataRef = CGDataProviderCreateWithData(bitmap, bitmap->getPixels(), s,
															 SkBitmap_ReleaseInfo);

    CGColorSpaceRef space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
    CGImageRef ref = CGImageCreate(w, h, bitsPerComponent,
                                   bitmap->bytesPerPixel() * 8,
                                   bitmap->rowBytes(), space, info, dataRef,
                                   NULL, false, kCGRenderingIntentDefault);
    CGColorSpaceRelease(space);
    CGDataProviderRelease(dataRef);
    return ref;
}

<commit_msg>fix config check to include SkColorPriv.h so we don't get the warning w/o need<commit_after>#include "SkCGUtils.h"
#include "SkBitmap.h"
#include "SkColorPriv.h"

extern CGImageRef SkCreateCGImageRef(const SkBitmap&);

static void SkBitmap_ReleaseInfo(void* info, const void* pixelData, size_t size) {
    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info);
    delete bitmap;
}

#define HAS_ARGB_SHIFTS(a, r, g, b) \
    (SK_A32_SHIFT == (a) && SK_R32_SHIFT == (r) \
    && SK_G32_SHIFT == (g) && SK_B32_SHIFT == (b))

static SkBitmap* prepareForImageRef(const SkBitmap& bm,
                                    size_t* bitsPerComponent,
                                    CGBitmapInfo* info) {
#if 0
    SkDebugf("---- %d %d %d %d\n", SK_A32_SHIFT, SK_R32_SHIFT,
             SK_G32_SHIFT, SK_B32_SHIFT);
#endif

    switch (bm.config()) {
        case SkBitmap::kARGB_8888_Config:
            *bitsPerComponent = 8;
#if defined(SK_CPU_LENDIAN) && HAS_ARGB_SHIFTS(24, 0, 8, 16) \
 || defined(SK_CPU_BENDIAN) && HAS_ARGB_SHIFTS(0, 24, 16, 8)
            *info = kCGBitmapByteOrder32Big |
                    kCGImageAlphaPremultipliedLast;
#elif defined(SK_CPU_LENDIAN) && HAS_ARGB_SHIFTS(24, 16, 8, 0) \
   || defined(SK_CPU_BENDIAN) && HAS_ARGB_SHIFTS(24, 16, 8, 0)
            // Matches the CGBitmapInfo that Apple recommends for best
            // performance, used by google chrome.
            *info = kCGBitmapByteOrder32Host |
                    kCGImageAlphaPremultipliedFirst;
#else
// ...add more formats as required...
#warning Cannot convert SkBitmap to CGImageRef with these shiftmasks. \
            This will probably not work.
            // Legacy behavior. Perhaps turn this into an error at some
            // point.
            *info = kCGBitmapByteOrder32Big |
                    kCGImageAlphaPremultipliedLast;
#endif
            break;
        case SkBitmap::kRGB_565_Config:
            // doesn't see quite right. Are they thinking 1555?
            *bitsPerComponent = 5;
            *info = kCGBitmapByteOrder16Little;
            break;
        case SkBitmap::kARGB_4444_Config:
            *bitsPerComponent = 4;
            *info = kCGBitmapByteOrder16Little | kCGImageAlphaPremultipliedLast;
            break;
        default:
            return NULL;
    }

    return new SkBitmap(bm);
}

#undef HAS_ARGB_SHIFTS

CGImageRef SkCreateCGImageRef(const SkBitmap& bm) {
    size_t bitsPerComponent;
    CGBitmapInfo info;

    SkBitmap* bitmap = prepareForImageRef(bm, &bitsPerComponent, &info);
    if (NULL == bitmap) {
        return NULL;
    }

    const int w = bitmap->width();
    const int h = bitmap->height();
    const size_t s = bitmap->getSize();

    // our provider "owns" the bitmap*, and will take care of deleting it
	// we initially lock it, so we can access the pixels. The bitmap will be deleted in the release
	// proc, which will in turn unlock the pixels
	bitmap->lockPixels();
    CGDataProviderRef dataRef = CGDataProviderCreateWithData(bitmap, bitmap->getPixels(), s,
															 SkBitmap_ReleaseInfo);

    CGColorSpaceRef space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
    CGImageRef ref = CGImageCreate(w, h, bitsPerComponent,
                                   bitmap->bytesPerPixel() * 8,
                                   bitmap->rowBytes(), space, info, dataRef,
                                   NULL, false, kCGRenderingIntentDefault);
    CGColorSpaceRelease(space);
    CGDataProviderRelease(dataRef);
    return ref;
}

<|endoftext|>


<commit_before>// Copyright © 2016 by Donald King <chronos@chronos-tachyon.net>
// Available under the MIT License. See LICENSE for details.

#include "base/token.h"

#include <mutex>

namespace base {

static std::mutex g_tok_mu;
static uint64_t g_tok_last = 0;

token_t next_token() noexcept {
  std::lock_guard<std::mutex> lock(g_tok_mu);
  return token_t(++g_tok_last);
}

}  // namespace base
<commit_msg>Use <atomic> for base::next_token().<commit_after>// Copyright © 2016 by Donald King <chronos@chronos-tachyon.net>
// Available under the MIT License. See LICENSE for details.

#include "base/token.h"

#include <atomic>
#include <cstdint>

namespace base {

static std::atomic<uint64_t> g_last;

token_t next_token() noexcept {
  return token_t(1 + g_last.fetch_add(1));
}

}  // namespace base
<|endoftext|>


<commit_before>/* Copyright 2021 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <fstream>
#include <memory>

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "flatbuffers/flatbuffers.h"  // from @flatbuffers
#include "tensorflow/lite/experimental/acceleration/compatibility/android_info.h"
#include "tensorflow/lite/experimental/acceleration/configuration/configuration_generated.h"
#include "tensorflow/lite/experimental/acceleration/mini_benchmark/big_little_affinity.h"
#include "tensorflow/lite/experimental/acceleration/mini_benchmark/validator.h"
#ifdef ENABLE_NNAPI_SL_TEST
#include "tensorflow/lite/nnapi/sl/include/SupportLibrary.h"
#endif /* ENABLE_NNAPI_SL_TEST */

extern const unsigned char TENSORFLOW_ACCELERATION_MODEL_DATA_VARIABLE[];
extern const int TENSORFLOW_ACCELERATION_MODEL_LENGTH_VARIABLE;

namespace tflite {
namespace acceleration {
namespace {

class LocalizerValidationRegressionTest : public ::testing::Test {
 protected:
  static void SetUpTestSuite() {
    int error = -1;
#if defined(__ANDROID__)
    AndroidInfo android_info;
    auto status = RequestAndroidInfo(&android_info);
    ASSERT_TRUE(status.ok());
    if (android_info.is_emulator) {
      std::cerr << "Running on an emulator, skipping processor affinity\n";
    } else {
      std::cerr << "Running on hardware, setting processor affinity\n";
      BigLittleAffinity affinity = GetAffinity();
      cpu_set_t set;
      CPU_ZERO(&set);
      for (int i = 0; i < 16; i++) {
        if (affinity.big_core_affinity & (0x1 << i)) {
          CPU_SET(i, &set);
        }
      }
      error = sched_setaffinity(getpid(), sizeof(set), &set);
      if (error == -1) {
        perror("sched_setaffinity failed");
      }
    }
#endif
    std::string dir = GetTestTmpDir();
    error = mkdir(dir.c_str(), 0777);
    if (error == -1) {
      if (errno != EEXIST) {
        perror("mkdir failed");
        ASSERT_TRUE(false);
      }
    }

    std::string path = ModelPath();
    (void)unlink(path.c_str());
    std::string contents(reinterpret_cast<const char*>(
                             TENSORFLOW_ACCELERATION_MODEL_DATA_VARIABLE),
                         TENSORFLOW_ACCELERATION_MODEL_LENGTH_VARIABLE);
    std::ofstream f(path, std::ios::binary);
    ASSERT_TRUE(f.is_open());
    f << contents;
    f.close();
    ASSERT_EQ(chmod(path.c_str(), 0500), 0);
  }
  static std::string ModelPath() { return GetTestTmpDir() + "/model.tflite"; }
  static std::string GetTestTmpDir() {
    const char* from_env = getenv("TEST_TMPDIR");
    if (from_env) {
      return from_env;
    }
#ifdef __ANDROID__
    return "/data/local/tmp";
#else
    return "/tmp";
#endif
  }
  void CheckValidation(const std::string& accelerator_name) {
    std::string path = ModelPath();
    const ComputeSettings* settings =
        flatbuffers::GetRoot<ComputeSettings>(fbb_.GetBufferPointer());
    int fd = open(path.c_str(), O_RDONLY);
    ASSERT_GE(fd, 0);
    struct stat stat_buf = {0};
    ASSERT_EQ(fstat(fd, &stat_buf), 0);
    auto validator =
        std::make_unique<Validator>(fd, 0, stat_buf.st_size, settings);
    close(fd);

    Validator::Results results;
    EXPECT_EQ(validator->RunValidation(&results), kMinibenchmarkSuccess);
    EXPECT_TRUE(results.ok);
    EXPECT_EQ(results.delegate_error, 0);
    if (accelerator_name != "CPU") {
      // For any non-CPU delegate, we validate that model execution was at least
      // partially delegated by expecting non-zero number of delegated kernels
      EXPECT_NE(results.delegated_kernels, 0);
    }

    for (const auto& metric : results.metrics) {
      int test_case = 0;
      std::cerr << "Metric " << metric.first;
      for (float v : metric.second) {
        std::cerr << " " << v;
        RecordProperty("[" + std::to_string(test_case++) + "] " +
                           accelerator_name + " " + metric.first,
                       std::to_string(v));
      }
      std::cerr << "\n";
    }
    std::cerr << "Compilation time us " << results.compilation_time_us
              << std::endl;
    RecordProperty(accelerator_name + " Compilation time us",
                   results.compilation_time_us);
    std::cerr << "Execution time us";
    int test_case = 0;
    int64_t total_execution_time_us = 0;
    for (int64_t t : results.execution_time_us) {
      std::cerr << " " << t;
      RecordProperty("[" + std::to_string(test_case++) + "] " +
                         accelerator_name + " Execution time us",
                     t);
      total_execution_time_us += t;
    }
    std::cerr << "\n";
    int64_t average_execution_time_us = total_execution_time_us / test_case;
    std::cerr << "Avg execution time us " << average_execution_time_us
              << std::endl;
    RecordProperty(accelerator_name + " Avg execution time us",
                   average_execution_time_us);
    std::cerr << std::endl;
  }
  flatbuffers::FlatBufferBuilder fbb_;
};

TEST_F(LocalizerValidationRegressionTest, Cpu) {
  fbb_.Finish(CreateComputeSettings(fbb_, ExecutionPreference_ANY,
                                    CreateTFLiteSettings(fbb_)));
  CheckValidation("CPU");
}

TEST_F(LocalizerValidationRegressionTest, Nnapi) {
  fbb_.Finish(
      CreateComputeSettings(fbb_, ExecutionPreference_ANY,
                            CreateTFLiteSettings(fbb_, Delegate_NNAPI)));
  AndroidInfo android_info;
  auto status = RequestAndroidInfo(&android_info);
  ASSERT_TRUE(status.ok());
  if (android_info.android_sdk_version >= "28") {
    CheckValidation("NNAPI");
  }
}

#ifdef ENABLE_NNAPI_SL_TEST
TEST_F(LocalizerValidationRegressionTest, NnapiSl) {
  const char* accelerator_name = getenv("TEST_ACCELERATOR_NAME");

  std::string support_library_file = GetTestTmpDir() + "/libnnapi_sl_driver.so";
  auto nnapi_sl_handle = nnapi::loadNnApiSupportLibrary(support_library_file);
  fbb_.Finish(CreateComputeSettings(
      fbb_, ExecutionPreference_ANY,
      CreateTFLiteSettings(
          fbb_, Delegate_NNAPI,
          CreateNNAPISettings(
              fbb_, fbb_.CreateString(accelerator_name ? accelerator_name : ""),
              /* cache_directory */ 0,
              /* model_token */ 0, NNAPIExecutionPreference_UNDEFINED,
              /* no_of_nnapi_instances_to_cache */ 0,
              /* fallback_settings */ 0,
              /* allow_nnapi_cpu_on_android_10_plus */ false,
              /* execution_priority */
              NNAPIExecutionPriority_NNAPI_PRIORITY_UNDEFINED,
              /* allow_dynamic_dimensions */ false,
              /* allow_fp16_precision_for_fp32 */ true,
              /* use_burst_computation */ false,
              reinterpret_cast<uint64_t>(nnapi_sl_handle->getFL5())),
          /* gpu_settings */ 0,
          /* hexagon_settings */ 0,
          /* xnnpack_settings */ 0,
          /* coreml_settings */ 0,
          /* cpu_settings */ 0,
          /* max_delegated_partitions */ 1)));
  AndroidInfo android_info;
  auto status = RequestAndroidInfo(&android_info);
  ASSERT_TRUE(status.ok());
  if (android_info.android_sdk_version >= "30") {
    CheckValidation("NNAPISL");
  }
}
#endif /* ENABLE_NNAPI_SL_TEST */

TEST_F(LocalizerValidationRegressionTest, Gpu) {
  AndroidInfo android_info;
  auto status = RequestAndroidInfo(&android_info);
  ASSERT_TRUE(status.ok());
  if (android_info.is_emulator) {
    std::cerr << "Skipping GPU on emulator\n";
    return;
  }
  fbb_.Finish(CreateComputeSettings(fbb_, ExecutionPreference_ANY,
                                    CreateTFLiteSettings(fbb_, Delegate_GPU)));
#ifdef __ANDROID__
  CheckValidation("GPU");
#endif  // __ANDROID__
}

}  // namespace
}  // namespace acceleration
}  // namespace tflite
<commit_msg>Introduce compilation flags for disabling platform nnapi delegate tests.<commit_after>/* Copyright 2021 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <fstream>
#include <memory>

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "flatbuffers/flatbuffers.h"  // from @flatbuffers
#include "tensorflow/lite/experimental/acceleration/compatibility/android_info.h"
#include "tensorflow/lite/experimental/acceleration/configuration/configuration_generated.h"
#include "tensorflow/lite/experimental/acceleration/mini_benchmark/big_little_affinity.h"
#include "tensorflow/lite/experimental/acceleration/mini_benchmark/validator.h"
#ifdef ENABLE_NNAPI_SL_TEST
#include "tensorflow/lite/nnapi/sl/include/SupportLibrary.h"
#endif /* ENABLE_NNAPI_SL_TEST */

extern const unsigned char TENSORFLOW_ACCELERATION_MODEL_DATA_VARIABLE[];
extern const int TENSORFLOW_ACCELERATION_MODEL_LENGTH_VARIABLE;

namespace tflite {
namespace acceleration {
namespace {

class LocalizerValidationRegressionTest : public ::testing::Test {
 protected:
  static void SetUpTestSuite() {
    int error = -1;
#if defined(__ANDROID__)
    AndroidInfo android_info;
    auto status = RequestAndroidInfo(&android_info);
    ASSERT_TRUE(status.ok());
    if (android_info.is_emulator) {
      std::cerr << "Running on an emulator, skipping processor affinity\n";
    } else {
      std::cerr << "Running on hardware, setting processor affinity\n";
      BigLittleAffinity affinity = GetAffinity();
      cpu_set_t set;
      CPU_ZERO(&set);
      for (int i = 0; i < 16; i++) {
        if (affinity.big_core_affinity & (0x1 << i)) {
          CPU_SET(i, &set);
        }
      }
      error = sched_setaffinity(getpid(), sizeof(set), &set);
      if (error == -1) {
        perror("sched_setaffinity failed");
      }
    }
#endif
    std::string dir = GetTestTmpDir();
    error = mkdir(dir.c_str(), 0777);
    if (error == -1) {
      if (errno != EEXIST) {
        perror("mkdir failed");
        ASSERT_TRUE(false);
      }
    }

    std::string path = ModelPath();
    (void)unlink(path.c_str());
    std::string contents(reinterpret_cast<const char*>(
                             TENSORFLOW_ACCELERATION_MODEL_DATA_VARIABLE),
                         TENSORFLOW_ACCELERATION_MODEL_LENGTH_VARIABLE);
    std::ofstream f(path, std::ios::binary);
    ASSERT_TRUE(f.is_open());
    f << contents;
    f.close();
    ASSERT_EQ(chmod(path.c_str(), 0500), 0);
  }
  static std::string ModelPath() { return GetTestTmpDir() + "/model.tflite"; }
  static std::string GetTestTmpDir() {
    const char* from_env = getenv("TEST_TMPDIR");
    if (from_env) {
      return from_env;
    }
#ifdef __ANDROID__
    return "/data/local/tmp";
#else
    return "/tmp";
#endif
  }
  void CheckValidation(const std::string& accelerator_name) {
    std::string path = ModelPath();
    const ComputeSettings* settings =
        flatbuffers::GetRoot<ComputeSettings>(fbb_.GetBufferPointer());
    int fd = open(path.c_str(), O_RDONLY);
    ASSERT_GE(fd, 0);
    struct stat stat_buf = {0};
    ASSERT_EQ(fstat(fd, &stat_buf), 0);
    auto validator =
        std::make_unique<Validator>(fd, 0, stat_buf.st_size, settings);
    close(fd);

    Validator::Results results;
    EXPECT_EQ(validator->RunValidation(&results), kMinibenchmarkSuccess);
    EXPECT_TRUE(results.ok);
    EXPECT_EQ(results.delegate_error, 0);
    if (accelerator_name != "CPU") {
      // For any non-CPU delegate, we validate that model execution was at least
      // partially delegated by expecting non-zero number of delegated kernels
      EXPECT_NE(results.delegated_kernels, 0);
    }

    for (const auto& metric : results.metrics) {
      int test_case = 0;
      std::cerr << "Metric " << metric.first;
      for (float v : metric.second) {
        std::cerr << " " << v;
        RecordProperty("[" + std::to_string(test_case++) + "] " +
                           accelerator_name + " " + metric.first,
                       std::to_string(v));
      }
      std::cerr << "\n";
    }
    std::cerr << "Compilation time us " << results.compilation_time_us
              << std::endl;
    RecordProperty(accelerator_name + " Compilation time us",
                   results.compilation_time_us);
    std::cerr << "Execution time us";
    int test_case = 0;
    int64_t total_execution_time_us = 0;
    for (int64_t t : results.execution_time_us) {
      std::cerr << " " << t;
      RecordProperty("[" + std::to_string(test_case++) + "] " +
                         accelerator_name + " Execution time us",
                     t);
      total_execution_time_us += t;
    }
    std::cerr << "\n";
    int64_t average_execution_time_us = total_execution_time_us / test_case;
    std::cerr << "Avg execution time us " << average_execution_time_us
              << std::endl;
    RecordProperty(accelerator_name + " Avg execution time us",
                   average_execution_time_us);
    std::cerr << std::endl;
  }
  flatbuffers::FlatBufferBuilder fbb_;
};

TEST_F(LocalizerValidationRegressionTest, Cpu) {
  fbb_.Finish(CreateComputeSettings(fbb_, ExecutionPreference_ANY,
                                    CreateTFLiteSettings(fbb_)));
  CheckValidation("CPU");
}

#ifndef DISABLE_PLATFORM_NNAPI_TEST
TEST_F(LocalizerValidationRegressionTest, Nnapi) {
  fbb_.Finish(
      CreateComputeSettings(fbb_, ExecutionPreference_ANY,
                            CreateTFLiteSettings(fbb_, Delegate_NNAPI)));
  AndroidInfo android_info;
  auto status = RequestAndroidInfo(&android_info);
  ASSERT_TRUE(status.ok());
  if (android_info.android_sdk_version >= "28") {
    CheckValidation("NNAPI");
  }
}
#endif  // DISABLE_PLATFORM_NNAPI_TEST

#ifdef ENABLE_NNAPI_SL_TEST
TEST_F(LocalizerValidationRegressionTest, NnapiSl) {
  const char* accelerator_name = getenv("TEST_ACCELERATOR_NAME");

  std::string support_library_file = GetTestTmpDir() + "/libnnapi_sl_driver.so";
  auto nnapi_sl_handle = nnapi::loadNnApiSupportLibrary(support_library_file);
  fbb_.Finish(CreateComputeSettings(
      fbb_, ExecutionPreference_ANY,
      CreateTFLiteSettings(
          fbb_, Delegate_NNAPI,
          CreateNNAPISettings(
              fbb_, fbb_.CreateString(accelerator_name ? accelerator_name : ""),
              /* cache_directory */ 0,
              /* model_token */ 0, NNAPIExecutionPreference_UNDEFINED,
              /* no_of_nnapi_instances_to_cache */ 0,
              /* fallback_settings */ 0,
              /* allow_nnapi_cpu_on_android_10_plus */ false,
              /* execution_priority */
              NNAPIExecutionPriority_NNAPI_PRIORITY_UNDEFINED,
              /* allow_dynamic_dimensions */ false,
              /* allow_fp16_precision_for_fp32 */ true,
              /* use_burst_computation */ false,
              reinterpret_cast<uint64_t>(nnapi_sl_handle->getFL5())),
          /* gpu_settings */ 0,
          /* hexagon_settings */ 0,
          /* xnnpack_settings */ 0,
          /* coreml_settings */ 0,
          /* cpu_settings */ 0,
          /* max_delegated_partitions */ 1)));
  AndroidInfo android_info;
  auto status = RequestAndroidInfo(&android_info);
  ASSERT_TRUE(status.ok());
  if (android_info.android_sdk_version >= "30") {
    CheckValidation("NNAPISL");
  }
}
#endif  // ENABLE_NNAPI_SL_TEST

TEST_F(LocalizerValidationRegressionTest, Gpu) {
  AndroidInfo android_info;
  auto status = RequestAndroidInfo(&android_info);
  ASSERT_TRUE(status.ok());
  if (android_info.is_emulator) {
    std::cerr << "Skipping GPU on emulator\n";
    return;
  }
  fbb_.Finish(CreateComputeSettings(fbb_, ExecutionPreference_ANY,
                                    CreateTFLiteSettings(fbb_, Delegate_GPU)));
#ifdef __ANDROID__
  CheckValidation("GPU");
#endif  // __ANDROID__
}

}  // namespace
}  // namespace acceleration
}  // namespace tflite
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// template<class T>
// class enable_shared_from_this
// {
// protected:
//     enable_shared_from_this();
//     enable_shared_from_this(enable_shared_from_this const&);
//     enable_shared_from_this& operator=(enable_shared_from_this const&);
//     ~enable_shared_from_this();
// public:
//     shared_ptr<T> shared_from_this();
//     shared_ptr<T const> shared_from_this() const;
//     weak_ptr<T> weak_from_this() noexcept;                         // C++17
//     weak_ptr<T const> weak_from_this() const noexecpt;             // C++17
// };

#include <memory>
#include <cassert>

#include "test_macros.h"

struct T
    : public std::enable_shared_from_this<T>
{
};

struct Y : T {};

struct Z : Y {};

void nullDeleter(void*) {}

int main()
{
    {  // https://llvm.org/bugs/show_bug.cgi?id=18843
    std::shared_ptr<T const> t1(new T);
    std::shared_ptr<T const> t2(std::make_shared<T>());
    }
    {
    std::shared_ptr<Y> p(new Z);
    std::shared_ptr<T> q = p->shared_from_this();
    assert(p == q);
    assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership
    }
    {
    std::shared_ptr<Y> p = std::make_shared<Z>();
    std::shared_ptr<T> q = p->shared_from_this();
    assert(p == q);
    assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership
    }
    // Test LWG issue 2529. Only reset '__weak_ptr_' when it's already expired.
    // http://cplusplus.github.io/LWG/lwg-active.html#2529.
    // Test two different ways:
    // * Using 'weak_from_this().expired()' in C++17.
    // * Using 'shared_from_this()' in all dialects.
    {

        T* ptr = new T;
        std::shared_ptr<T> s(ptr);
        {
            // Don't re-initialize the "enabled_shared_from_this" base
            // because it already references a non-expired shared_ptr.
            std::shared_ptr<T> s2(ptr, &nullDeleter);
        }
#if TEST_STD_VER > 14
        // The enabled_shared_from_this base should still be referencing
        // the original shared_ptr.
        assert(!ptr->weak_from_this().expired());
#endif
#ifndef TEST_HAS_NO_EXCEPTIONS
        {
            try {
                std::shared_ptr<T> new_s = ptr->shared_from_this();
                assert(new_s == s);
            } catch (std::bad_weak_ptr const&) {
                assert(false);
            } catch (...) {
                assert(false);
            }
        }
#endif
    }
    // Test LWG issue 2529 again. This time check that an expired pointer
    // is replaced.
    {
        T* ptr = new T;
        std::weak_ptr<T> weak;
        {
            std::shared_ptr<T> s(ptr, &nullDeleter);
            assert(ptr->shared_from_this() == s);
            weak = s;
            assert(!weak.expired());
        }
        assert(weak.expired());
        weak.reset();
#ifndef TEST_HAS_NO_EXCEPTIONS
        try {
            ptr->shared_from_this();
            assert(false);
        } catch (std::bad_weak_ptr const&) {
        } catch (...) { assert(false); }
#endif
        {
            std::shared_ptr<T> s2(ptr, &nullDeleter);
            assert(ptr->shared_from_this() == s2);
        }
        delete ptr;
    }
    // Test weak_from_this_methods
#if TEST_STD_VER > 14
    {
        T* ptr = new T;
        const T* cptr = ptr;

        static_assert(noexcept(ptr->weak_from_this()), "Operation must be noexcept");
        static_assert(noexcept(cptr->weak_from_this()), "Operation must be noexcept");

        std::weak_ptr<T> my_weak = ptr->weak_from_this();
        assert(my_weak.expired());

        std::weak_ptr<T const> my_const_weak = cptr->weak_from_this();
        assert(my_const_weak.expired());

        // Enable shared_from_this with ptr.
        std::shared_ptr<T> sptr(ptr);
        my_weak = ptr->weak_from_this();
        assert(!my_weak.expired());
        assert(my_weak.lock().get() == ptr);
    }
#endif
}
<commit_msg>Remove enable_shared_from_this test since it leaks the control block and fails with ASAN<commit_after>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// template<class T>
// class enable_shared_from_this
// {
// protected:
//     enable_shared_from_this();
//     enable_shared_from_this(enable_shared_from_this const&);
//     enable_shared_from_this& operator=(enable_shared_from_this const&);
//     ~enable_shared_from_this();
// public:
//     shared_ptr<T> shared_from_this();
//     shared_ptr<T const> shared_from_this() const;
//     weak_ptr<T> weak_from_this() noexcept;                         // C++17
//     weak_ptr<T const> weak_from_this() const noexecpt;             // C++17
// };

#include <memory>
#include <cassert>

#include "test_macros.h"

struct T
    : public std::enable_shared_from_this<T>
{
};

struct Y : T {};

struct Z : Y {};

void nullDeleter(void*) {}

int main()
{
    {  // https://llvm.org/bugs/show_bug.cgi?id=18843
    std::shared_ptr<T const> t1(new T);
    std::shared_ptr<T const> t2(std::make_shared<T>());
    }
    {
    std::shared_ptr<Y> p(new Z);
    std::shared_ptr<T> q = p->shared_from_this();
    assert(p == q);
    assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership
    }
    {
    std::shared_ptr<Y> p = std::make_shared<Z>();
    std::shared_ptr<T> q = p->shared_from_this();
    assert(p == q);
    assert(!p.owner_before(q) && !q.owner_before(p)); // p and q share ownership
    }
    // Test LWG issue 2529. Only reset '__weak_ptr_' when it's already expired.
    // http://cplusplus.github.io/LWG/lwg-active.html#2529.
    // Test two different ways:
    // * Using 'weak_from_this().expired()' in C++17.
    // * Using 'shared_from_this()' in all dialects.
    {

        T* ptr = new T;
        std::shared_ptr<T> s(ptr);
        {
            // Don't re-initialize the "enabled_shared_from_this" base
            // because it already references a non-expired shared_ptr.
            std::shared_ptr<T> s2(ptr, &nullDeleter);
        }
#if TEST_STD_VER > 14
        // The enabled_shared_from_this base should still be referencing
        // the original shared_ptr.
        assert(!ptr->weak_from_this().expired());
#endif
#ifndef TEST_HAS_NO_EXCEPTIONS
        {
            try {
                std::shared_ptr<T> new_s = ptr->shared_from_this();
                assert(new_s == s);
            } catch (std::bad_weak_ptr const&) {
                assert(false);
            } catch (...) {
                assert(false);
            }
        }
#endif
    }
    // Test weak_from_this_methods
#if TEST_STD_VER > 14
    {
        T* ptr = new T;
        const T* cptr = ptr;

        static_assert(noexcept(ptr->weak_from_this()), "Operation must be noexcept");
        static_assert(noexcept(cptr->weak_from_this()), "Operation must be noexcept");

        std::weak_ptr<T> my_weak = ptr->weak_from_this();
        assert(my_weak.expired());

        std::weak_ptr<T const> my_const_weak = cptr->weak_from_this();
        assert(my_const_weak.expired());

        // Enable shared_from_this with ptr.
        std::shared_ptr<T> sptr(ptr);
        my_weak = ptr->weak_from_this();
        assert(!my_weak.expired());
        assert(my_weak.lock().get() == ptr);
    }
#endif
}
<|endoftext|>