// Copyright 2018 The clvk authors.
//
// 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 <algorithm>
#include <cstring>
#include <filesystem>
#include <iostream>
#include <map>
#include <sstream>
#include <system_error>
#include <utility>
#include <vector>

#include <vulkan/vulkan.h>

#include "clspv/Sampler.h"
#include "utils.hpp"

#ifdef CLSPV_ONLINE_COMPILER
#ifdef ENABLE_SPIRV_IL
#include "LLVMSPIRVLib.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/Support/CommandLine.h" // FIXME(#380) remove
#include "llvm/Support/raw_ostream.h"
#endif
#include "clspv/Compiler.h"
#endif

#include "spirv-tools/linker.hpp"
#include "spirv-tools/optimizer.hpp"
#include "spirv/unified1/NonSemanticClspvReflection.h"
#include "spirv/unified1/spirv.hpp"

#include "config.hpp"
#include "init.hpp"
#include "log.hpp"
#include "program.hpp"
#include "tracing.hpp"

struct membuf : public std::streambuf {
    membuf(const unsigned char* begin, const unsigned char* end) {
        auto sbegin =
            reinterpret_cast<char*>(const_cast<unsigned char*>(begin));
        auto send = reinterpret_cast<char*>(const_cast<unsigned char*>(end));
        setg(sbegin, sbegin, send);
    }
    membuf(unsigned char* begin, unsigned char* end) {
        auto sbegin = reinterpret_cast<char*>(begin);
        auto send = reinterpret_cast<char*>(end);
        setp(sbegin, send);
    }
    pos_type seekoff(off_type off, std::ios_base::seekdir dir,
                     std::ios_base::openmode which) override {
        UNUSED(which);
        char* whence = eback();
        if (dir == std::ios_base::cur) {
            whence = gptr();
        } else if (dir == std::ios_base::end) {
            whence = egptr();
        }
        char* to = whence + off;
        if (to >= eback() && to <= egptr()) {
            setg(eback(), to, egptr());
            return gptr() - eback();
        }
        return -1;
    }

    pos_type seekpos(pos_type pos, std::ios_base::openmode which) override {
        UNUSED(which);
        char* to = eback() + pos;
        if (to >= eback() && to <= egptr()) {
            setg(eback(), to, egptr());
            return gptr() - eback();
        }
        return -1;
    }
};

struct reflection_parse_data {
    uint32_t uint_id = 0;
    std::unordered_map<uint32_t, uint32_t> constants;
    std::unordered_map<uint32_t, std::string> strings;
    spir_binary* binary;
    std::unordered_map<uint32_t, kernel_argument_info> arg_infos;
};

spv_result_t parse_reflection(void* user_data,
                              const spv_parsed_instruction_t* inst) {
    // Helper function to map instruction to argument type.
    auto inst_to_arg_kind = [](uint32_t inst) {
        switch (static_cast<NonSemanticClspvReflectionInstructions>(inst)) {
        case NonSemanticClspvReflectionArgumentStorageBuffer:
            return kernel_argument_kind::buffer;
        case NonSemanticClspvReflectionArgumentUniform:
            return kernel_argument_kind::buffer_ubo;
        case NonSemanticClspvReflectionArgumentPodStorageBuffer:
            return kernel_argument_kind::pod;
        case NonSemanticClspvReflectionArgumentPodUniform:
            return kernel_argument_kind::pod_ubo;
        case NonSemanticClspvReflectionArgumentPodPushConstant:
            return kernel_argument_kind::pod_pushconstant;
        case NonSemanticClspvReflectionArgumentPointerUniform:
            return kernel_argument_kind::pointer_ubo;
        case NonSemanticClspvReflectionArgumentPointerPushConstant:
            return kernel_argument_kind::pointer_pushconstant;
        case NonSemanticClspvReflectionArgumentSampledImage:
            return kernel_argument_kind::sampled_image;
        case NonSemanticClspvReflectionArgumentStorageImage:
            return kernel_argument_kind::storage_image;
        case NonSemanticClspvReflectionArgumentStorageTexelBuffer:
            return kernel_argument_kind::storage_texel_buffer;
        case NonSemanticClspvReflectionArgumentUniformTexelBuffer:
            return kernel_argument_kind::uniform_texel_buffer;
        case NonSemanticClspvReflectionArgumentSampler:
            return kernel_argument_kind::sampler;
        case NonSemanticClspvReflectionArgumentWorkgroup:
            return kernel_argument_kind::local;
        default:
            cvk_error_fn("Unhandled reflection instruction for arg kind");
            break;
        }
        return kernel_argument_kind::buffer;
    };

    // Helper function to map instruction to push constant type.
    auto inst_to_push_constant = [](uint32_t inst) {
        switch (static_cast<NonSemanticClspvReflectionInstructions>(inst)) {
        case NonSemanticClspvReflectionPushConstantGlobalOffset:
            return pushconstant::global_offset;
        case NonSemanticClspvReflectionPushConstantEnqueuedLocalSize:
            return pushconstant::enqueued_local_size;
        case NonSemanticClspvReflectionPushConstantGlobalSize:
            return pushconstant::global_size;
        case NonSemanticClspvReflectionPushConstantRegionOffset:
            return pushconstant::region_offset;
        case NonSemanticClspvReflectionPushConstantNumWorkgroups:
            return pushconstant::num_workgroups;
        case NonSemanticClspvReflectionPushConstantRegionGroupOffset:
            return pushconstant::region_group_offset;
        case NonSemanticClspvReflectionImageArgumentInfoChannelOrderPushConstant:
            return pushconstant::image_metadata;
        case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypePushConstant:
            return pushconstant::image_metadata;
        case NonSemanticClspvReflectionConstantDataPointerPushConstant:
            return pushconstant::module_constants_pointer;
        case NonSemanticClspvReflectionPrintfBufferPointerPushConstant:
            return pushconstant::printf_buffer_pointer;
        case NonSemanticClspvReflectionNormalizedSamplerMaskPushConstant:
            return pushconstant::normalized_sampler_mask;
        default:
            cvk_error_fn("Unhandled reflection instruction for push constant");
            break;
        }
        return pushconstant::global_offset;
    };

    auto* parse_data = reinterpret_cast<reflection_parse_data*>(user_data);
    switch (inst->opcode) {
    case spv::OpTypeInt:
        if (inst->words[2] == 32 && inst->words[3] == 0) {
            parse_data->uint_id = inst->result_id;
        }
        break;
    case spv::OpConstant:
        if (inst->words[1] == parse_data->uint_id) {
            parse_data->constants[inst->result_id] = inst->words[3];
        }
        break;
    case spv::OpString:
        parse_data->strings[inst->result_id] =
            std::string(reinterpret_cast<const char*>(&inst->words[2]));
        break;
    case spv::OpExtInst:
        if (inst->ext_inst_type ==
            SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION) {
            auto ext_inst = inst->words[4];
            switch (ext_inst) {
            case NonSemanticClspvReflectionKernel: {
                // Record the kernel name.
                const auto& name = parse_data->strings[inst->words[6]];

                const auto& num_args = parse_data->constants[inst->words[7]];
                const auto& flags = parse_data->constants[inst->words[8]];
                const auto& attributes = parse_data->strings[inst->words[9]];

                parse_data->strings[inst->result_id] = name;
                parse_data->binary->add_kernel(name, num_args, attributes,
                                               flags);
                break;
            }
            case NonSemanticClspvReflectionArgumentInfo: {
                // Record the argument info.
                kernel_argument_info info;
                info.name = parse_data->strings[inst->words[5]];
                if (inst->num_operands > 6) {
                    info.type_name = parse_data->strings[inst->words[6]];
                    info.address_qualifier =
                        parse_data->constants[inst->words[7]];
                    info.access_qualifier =
                        parse_data->constants[inst->words[8]];
                    info.type_qualifier = parse_data->constants[inst->words[9]];
                    info.extended_valid = true;
                }
                parse_data->arg_infos[inst->result_id] = info;
                break;
            }
            case NonSemanticClspvReflectionNormalizedSamplerMaskPushConstant: {
                auto kernel = parse_data->strings[inst->words[5]];
                auto ordinal = parse_data->constants[inst->words[6]];
                auto offset = parse_data->constants[inst->words[7]];
                auto size = parse_data->constants[inst->words[8]];
                parse_data->binary->add_sampler_metadata(kernel, ordinal,
                                                         offset);
                auto pc = inst_to_push_constant(ext_inst);
                parse_data->binary->add_push_constant(pc, {offset, size});
                break;
            }
            case NonSemanticClspvReflectionImageArgumentInfoChannelOrderPushConstant: {
                auto kernel = parse_data->strings[inst->words[5]];
                auto ordinal = parse_data->constants[inst->words[6]];
                auto offset = parse_data->constants[inst->words[7]];
                auto size = parse_data->constants[inst->words[8]];
                parse_data->binary->add_image_channel_order_metadata(
                    kernel, ordinal, offset);
                auto pc = inst_to_push_constant(ext_inst);
                parse_data->binary->add_push_constant(pc, {offset, size});
                break;
            }
            case NonSemanticClspvReflectionImageArgumentInfoChannelDataTypePushConstant: {
                auto kernel = parse_data->strings[inst->words[5]];
                auto ordinal = parse_data->constants[inst->words[6]];
                auto offset = parse_data->constants[inst->words[7]];
                auto size = parse_data->constants[inst->words[8]];
                parse_data->binary->add_image_channel_data_type_metadata(
                    kernel, ordinal, offset);
                auto pc = inst_to_push_constant(ext_inst);
                parse_data->binary->add_push_constant(pc, {offset, size});
                break;
            }
            case NonSemanticClspvReflectionArgumentStorageBuffer:
            case NonSemanticClspvReflectionArgumentUniform:
            case NonSemanticClspvReflectionArgumentSampledImage:
            case NonSemanticClspvReflectionArgumentStorageImage:
            case NonSemanticClspvReflectionArgumentStorageTexelBuffer:
            case NonSemanticClspvReflectionArgumentUniformTexelBuffer:
            case NonSemanticClspvReflectionArgumentSampler: {
                // These arguments have descriptor set, binding and an optional
                // arg info.
                auto kernel = parse_data->strings[inst->words[5]];
                auto ordinal = parse_data->constants[inst->words[6]];
                auto descriptor_set = parse_data->constants[inst->words[7]];
                if (descriptor_set >= spir_binary::MAX_DESCRIPTOR_SETS)
                    return SPV_ERROR_INVALID_DATA;
                auto binding = parse_data->constants[inst->words[8]];
                kernel_argument_info arg_info;
                if (inst->num_operands == 9) {
                    arg_info = parse_data->arg_infos[inst->words[9]];
                }
                auto kind = inst_to_arg_kind(ext_inst);
                kernel_argument arg = {arg_info, ordinal, descriptor_set,
                                       binding,  0,       0,
                                       kind,     0,       0};
                parse_data->binary->add_kernel_argument(kernel, std::move(arg));
                break;
            }
            case NonSemanticClspvReflectionArgumentPodStorageBuffer:
            case NonSemanticClspvReflectionArgumentPodUniform:
            case NonSemanticClspvReflectionArgumentPointerUniform: {
                // These arguments have descriptor set, binding, offset, size
                // and an optional arg info.
                auto kernel = parse_data->strings[inst->words[5]];
                auto ordinal = parse_data->constants[inst->words[6]];
                auto descriptor_set = parse_data->constants[inst->words[7]];
                if (descriptor_set >= spir_binary::MAX_DESCRIPTOR_SETS)
                    return SPV_ERROR_INVALID_DATA;
                auto binding = parse_data->constants[inst->words[8]];
                auto offset = parse_data->constants[inst->words[9]];
                auto size = parse_data->constants[inst->words[10]];
                kernel_argument_info arg_info;
                if (inst->num_operands == 11) {
                    arg_info = parse_data->arg_infos[inst->words[11]];
                }
                auto kind = inst_to_arg_kind(ext_inst);
                kernel_argument arg = {arg_info, ordinal, descriptor_set,
                                       binding,  offset,  size,
                                       kind,     0,       0};
                parse_data->binary->add_kernel_argument(kernel, std::move(arg));
                break;
            }
            case NonSemanticClspvReflectionArgumentPodPushConstant:
            case NonSemanticClspvReflectionArgumentPointerPushConstant: {
                // These arguments have offset, size and an optional arg info.
                auto kernel = parse_data->strings[inst->words[5]];
                auto ordinal = parse_data->constants[inst->words[6]];
                auto offset = parse_data->constants[inst->words[7]];
                auto size = parse_data->constants[inst->words[8]];
                kernel_argument_info arg_info;
                if (inst->num_operands == 9) {
                    arg_info = parse_data->arg_infos[inst->words[9]];
                }
                auto kind = inst_to_arg_kind(ext_inst);
                kernel_argument arg = {arg_info, ordinal, 0, 0, offset,
                                       size,     kind,    0, 0};
                parse_data->binary->add_kernel_argument(kernel, std::move(arg));
                break;
            }
            case NonSemanticClspvReflectionWorkgroupVariableSize: {
                auto size = parse_data->constants[inst->words[6]];
                parse_data->binary->add_workgroup_variable_size(size);
                break;
            }
            case NonSemanticClspvReflectionArgumentWorkgroup: {
                // These arguments have spec id, elem size and an optional arg
                // info.
                auto kernel = parse_data->strings[inst->words[5]];
                auto ordinal = parse_data->constants[inst->words[6]];
                auto spec_id = parse_data->constants[inst->words[7]];
                auto size = parse_data->constants[inst->words[8]];
                kernel_argument_info arg_info;
                if (inst->num_operands == 9) {
                    arg_info = parse_data->arg_infos[inst->words[9]];
                }
                auto kind = inst_to_arg_kind(ext_inst);
                kernel_argument arg = {arg_info, ordinal, 0,       0,   0,
                                       0,        kind,    spec_id, size};
                parse_data->binary->add_kernel_argument(kernel, std::move(arg));
                break;
            }
            case NonSemanticClspvReflectionSpecConstantWorkgroupSize: {
                // Reflection encodes all three spec ids in a single
                // instruction.
                auto x_id = parse_data->constants[inst->words[5]];
                auto y_id = parse_data->constants[inst->words[6]];
                auto z_id = parse_data->constants[inst->words[7]];
                parse_data->binary->add_spec_constant(
                    spec_constant::workgroup_size_x, x_id);
                parse_data->binary->add_spec_constant(
                    spec_constant::workgroup_size_y, y_id);
                parse_data->binary->add_spec_constant(
                    spec_constant::workgroup_size_z, z_id);
                break;
            }
            case NonSemanticClspvReflectionSpecConstantGlobalOffset: {
                // Reflection encodes all three spec ids in a single
                // instruction.
                auto x_id = parse_data->constants[inst->words[5]];
                auto y_id = parse_data->constants[inst->words[6]];
                auto z_id = parse_data->constants[inst->words[7]];
                parse_data->binary->add_spec_constant(
                    spec_constant::global_offset_x, x_id);
                parse_data->binary->add_spec_constant(
                    spec_constant::global_offset_y, y_id);
                parse_data->binary->add_spec_constant(
                    spec_constant::global_offset_z, z_id);
                break;
            }
            case NonSemanticClspvReflectionSpecConstantWorkDim: {
                auto dim_id = parse_data->constants[inst->words[5]];
                parse_data->binary->add_spec_constant(spec_constant::work_dim,
                                                      dim_id);
                break;
            }
            case NonSemanticClspvReflectionSpecConstantSubgroupMaxSize: {
                auto size_id = parse_data->constants[inst->words[5]];
                parse_data->binary->add_spec_constant(
                    spec_constant::subgroup_max_size, size_id);
                break;
            }
            case NonSemanticClspvReflectionPushConstantGlobalOffset:
            case NonSemanticClspvReflectionPushConstantEnqueuedLocalSize:
            case NonSemanticClspvReflectionPushConstantGlobalSize:
            case NonSemanticClspvReflectionPushConstantRegionOffset:
            case NonSemanticClspvReflectionPushConstantNumWorkgroups:
            case NonSemanticClspvReflectionPushConstantRegionGroupOffset: {
                auto offset = parse_data->constants[inst->words[5]];
                auto size = parse_data->constants[inst->words[6]];
                auto pc = inst_to_push_constant(ext_inst);
                parse_data->binary->add_push_constant(pc, {offset, size});
                break;
            }
            case NonSemanticClspvReflectionLiteralSampler: {
                // Track descriptor set and binding. Decode the sampler mask.
                auto descriptor_set = parse_data->constants[inst->words[5]];
                if (descriptor_set >= spir_binary::MAX_DESCRIPTOR_SETS)
                    return SPV_ERROR_INVALID_DATA;
                auto binding = parse_data->constants[inst->words[6]];
                auto mask = parse_data->constants[inst->words[7]];
                uint32_t coords = mask & clspv::kSamplerNormalizedCoordsMask;
                bool normalized_coords =
                    coords == clspv::CLK_NORMALIZED_COORDS_TRUE;
                cl_addressing_mode addressing;
                switch (mask & clspv::kSamplerAddressMask) {
                case clspv::CLK_ADDRESS_NONE:
                default:
                    addressing = CL_ADDRESS_NONE;
                    break;
                case clspv::CLK_ADDRESS_CLAMP_TO_EDGE:
                    addressing = CL_ADDRESS_CLAMP_TO_EDGE;
                    break;
                case clspv::CLK_ADDRESS_CLAMP:
                    addressing = CL_ADDRESS_CLAMP;
                    break;
                case clspv::CLK_ADDRESS_MIRRORED_REPEAT:
                    addressing = CL_ADDRESS_MIRRORED_REPEAT;
                    break;
                case clspv::CLK_ADDRESS_REPEAT:
                    addressing = CL_ADDRESS_REPEAT;
                    break;
                }
                cl_filter_mode filter;
                switch (mask & clspv::kSamplerFilterMask) {
                case clspv::CLK_FILTER_NEAREST:
                default:
                    filter = CL_FILTER_NEAREST;
                    break;
                case clspv::CLK_FILTER_LINEAR:
                    filter = CL_FILTER_LINEAR;
                    break;
                }
                parse_data->binary->add_literal_sampler(
                    {descriptor_set, binding, normalized_coords, addressing,
                     filter});
                break;
            }
            case NonSemanticClspvReflectionPropertyRequiredWorkgroupSize: {
                auto kernel = parse_data->strings[inst->words[5]];
                auto x = parse_data->constants[inst->words[6]];
                auto y = parse_data->constants[inst->words[7]];
                auto z = parse_data->constants[inst->words[8]];
                parse_data->binary->set_required_work_group_size(kernel, x, y,
                                                                 z);
                break;
            }
            case NonSemanticClspvReflectionConstantDataStorageBuffer:
            case NonSemanticClspvReflectionConstantDataPointerPushConstant: {

                auto char2int = [](char c) {
                    if (c >= '0' && c <= '9')
                        return c - '0';
                    if (c >= 'A' && c <= 'F')
                        return c - 'A' + 10;
                    if (c >= 'a' && c <= 'f')
                        return c - 'a' + 10;
                    return 0;
                };

                auto hex2bin = [&char2int](const char* str, char* bin) {
                    while (str[0] && str[1]) {
                        *(bin++) = char2int(str[0]) * 16 + char2int(str[1]);
                        str += 2;
                    }
                };

                auto data = parse_data->strings[inst->words[7]];
                if (data.size() & 1) {
                    cvk_error_fn("invalid constant data buffer string (odd "
                                 "number of digits)");
                    return SPV_ERROR_INVALID_DATA;
                }
                constant_data_buffer_info binfo{};
                auto data_size = data.size() / 2;
                binfo.data.resize(data_size);
                hex2bin(data.c_str(), binfo.data.data());
                if (ext_inst ==
                    NonSemanticClspvReflectionConstantDataStorageBuffer) {
                    binfo.type = module_buffer_type::storage_buffer;
                    binfo.set = parse_data->constants[inst->words[5]];
                    if (binfo.set >= spir_binary::MAX_DESCRIPTOR_SETS)
                        return SPV_ERROR_INVALID_DATA;
                    binfo.binding = parse_data->constants[inst->words[6]];

                } else {
                    binfo.type = module_buffer_type::pointer_push_constant;
                    binfo.pc_offset = parse_data->constants[inst->words[5]];
                    parse_data->binary->add_push_constant(
                        pushconstant::module_constants_pointer,
                        {binfo.pc_offset, 8u});
                }
                parse_data->binary->set_constant_data_buffer(binfo);
                break;
            }
            case NonSemanticClspvReflectionPrintfInfo: {
                uint32_t printf_id = parse_data->constants[inst->words[5]];
                std::string printf_string = parse_data->strings[inst->words[6]];
                std::vector<uint32_t> printf_arg_sizes;
                for (int i = 6; i < inst->num_operands; i++) {
                    printf_arg_sizes.push_back(
                        parse_data
                            ->constants[inst->words[inst->operands[i].offset]]);
                }
                parse_data->binary->add_printf_descriptor(
                    {printf_id, printf_string, printf_arg_sizes});
                break;
            }
            case NonSemanticClspvReflectionPrintfBufferStorageBuffer: {
                printf_buffer_desc_info binfo;
                binfo.type = module_buffer_type::storage_buffer;
                binfo.set = parse_data->constants[inst->words[5]];
                binfo.binding = parse_data->constants[inst->words[6]];
                binfo.size = parse_data->constants[inst->words[7]];
                parse_data->binary->set_printf_buffer_info(binfo);
                break;
            }
            case NonSemanticClspvReflectionPrintfBufferPointerPushConstant: {
                printf_buffer_desc_info binfo;
                binfo.type = module_buffer_type::pointer_push_constant;
                binfo.pc_offset = parse_data->constants[inst->words[5]];
                binfo.size = parse_data->constants[inst->words[7]];
                parse_data->binary->set_printf_buffer_info(binfo);
                parse_data->binary->add_push_constant(
                    pushconstant::printf_buffer_pointer, {binfo.pc_offset, 8u});
                break;
            }
            default:
                return SPV_ERROR_INVALID_DATA;
            }
        }
        break;
    default:
        break;
    }

    return SPV_SUCCESS;
}

bool spir_binary::load(const char* fname) {
    std::ifstream ifile;

    ifile.open(fname, std::ios::in | std::ios::binary);

    if (!ifile.is_open()) {
        cvk_error("Failed to open %s", fname);
        return false;
    }

    ifile.seekg(0, std::ios::end);
    uint32_t size = ifile.tellg();
    ifile.seekg(0, std::ios::beg);

    return load(ifile, size);
}

bool spir_binary::load(std::istream& istream, uint32_t size) {
    m_code.assign(size / SPIR_WORD_SIZE, 0);
    istream.read(reinterpret_cast<char*>(m_code.data()), size);

    if (!istream.good()) {
        cvk_warn("Failed to load SPIR-V (size: %u)", size);
        return false;
    }

    return true;
}

bool spir_binary::read(const unsigned char* src, size_t size) {
    m_loaded_from_binary = true;
    membuf bufview(src, src + size);
    std::istream istream(&bufview);
    return load(istream, size);
}

bool spir_binary::save(std::ostream& ostream) const {
    ostream.write(reinterpret_cast<const char*>(m_code.data()), size());
    return ostream.good();
}

bool spir_binary::save(const char* fname) const {
    std::ofstream ofile;

    ofile.open(fname, std::ios::out | std::ios::binary);

    if (!ofile.is_open()) {
        return false;
    }

    return save(ofile);
}

size_t spir_binary::size() const { return m_code.size() * SPIR_WORD_SIZE; }

bool spir_binary::write(unsigned char* dst) const {
    membuf bufview(dst, dst + size());
    std::ostream ostream(&bufview);
    return save(ostream);
}

void spir_binary::use(std::vector<uint32_t>&& src) { m_code = std::move(src); }

void spir_binary::set_target_env(spv_target_env env) {
    spvContextDestroy(m_context);
    m_context = spvContextCreate(env);
}

bool spir_binary::validate(const spirv_validation_options& val_options) const {
    spv_diagnostic diag;
    spv_validator_options options = spvValidatorOptionsCreate();
    spvValidatorOptionsSetUniformBufferStandardLayout(
        options, val_options.uniform_buffer_std_layout);
    spv_const_binary_t binary{m_code.data(), m_code.size()};
    spv_result_t res =
        spvValidateWithOptions(m_context, options, &binary, &diag);
    spvDiagnosticPrint(diag);
    spvDiagnosticDestroy(diag);
    spvValidatorOptionsDestroy(options);
    return res == SPV_SUCCESS;
}

bool spir_binary::strip_reflection(std::vector<uint32_t>* stripped) {
    const spvtools::MessageConsumer consumer =
        [](spv_message_level_t level, const char*,
           const spv_position_t& position, const char* message) {

#define msgtpl "spvtools says '%s' at position %zu"
            switch (level) {
            case SPV_MSG_FATAL:
            case SPV_MSG_INTERNAL_ERROR:
            case SPV_MSG_ERROR:
                cvk_error(msgtpl, message, position.index);
                break;
            case SPV_MSG_WARNING:
                cvk_warn(msgtpl, message, position.index);
                break;
            case SPV_MSG_INFO:
                cvk_info(msgtpl, message, position.index);
                break;
            case SPV_MSG_DEBUG:
                cvk_debug(msgtpl, message, position.index);
                break;
            }
#undef msgtpl
        };

#if COMPILER_AVAILABLE || USING_SWIFTSHADER
    spvtools::Optimizer opt(m_target_env);
    opt.SetMessageConsumer(consumer);
    opt.RegisterPass(spvtools::CreateStripReflectInfoPass());
    spvtools::OptimizerOptions options;
    options.set_run_validator(false);
    if (!opt.Run(m_code.data(), m_code.size(), stripped, options)) {
        return false;
    }
#else
    *stripped = m_code;
#endif
    return true;
}

bool spir_binary::load_descriptor_map() {
    reflection_parse_data parse_data;
    parse_data.binary = this;

    // TODO: The parser assumes a valid SPIR-V module, but validation is not
    // run until later.
    auto result =
        spvBinaryParse(m_context, &parse_data, m_code.data(), m_code.size(),
                       nullptr, parse_reflection, nullptr);
    if (result != SPV_SUCCESS) {
        cvk_error_fn("Parsing SPIR-V module reflection failed: %d", result);
        return false;
    }

    return true;
}

bool spir_binary::get_capabilities(
    std::vector<spv::Capability>& capabilities) const {
    // Callback for receiving parsed instructions.
    // The `user_data` parameter will be a pointer to the vector of
    // capabilities (we cannot use a lambda capture for this as it prevents the
    // lambda from being able to be converted to a function pointer).
    auto parse_inst = [](void* user_data,
                         const spv_parsed_instruction_t* inst) {
        // Stop parsing at first instruction that is not an OpCapability.
        if (inst->opcode != spv::Op::OpCapability) {
            return SPV_END_OF_STREAM;
        }

        // Add the capability to the list.
        uint32_t capability = inst->words[inst->operands[0].offset];
        auto capabilities =
            reinterpret_cast<std::vector<spv::Capability>*>(user_data);
        capabilities->push_back(static_cast<spv::Capability>(capability));

        return SPV_SUCCESS;
    };

    // Parse the SPIR-V binary to build the list of required capabilities.
    spv_result_t result =
        spvBinaryParse(m_context, &capabilities, m_code.data(), m_code.size(),
                       nullptr, parse_inst, nullptr);
    if (result != SPV_SUCCESS && result != SPV_END_OF_STREAM) {
        cvk_error_fn("Parsing SPIR-V module failed: %d", result);
        return false;
    }
    return true;
}

namespace {

#if COMPILER_AVAILABLE
bool save_cstring_to_file(
    const std::string& fname, const char* data, size_t size,
    std::ios_base::openmode open_mode = std::ios_base::out) {
    std::filesystem::path ofname(fname);
    if (ofname.has_parent_path()) {
        std::error_code error;
        std::filesystem::create_directories(ofname.parent_path(), error);
        if (error) {
            cvk_error_fn("create_directories failed: '%s' (%u)",
                         error.message().c_str(), error.value());
            return false;
        }
    }
    std::ofstream ofile{fname, open_mode};

    if (!ofile.is_open()) {
        return false;
    }

    ofile.write(data, size);
    ofile.close();

    return ofile.good();
}

bool save_string_to_file(const std::string& fname, const std::string& text) {
    return save_cstring_to_file(fname, text.c_str(), text.size());
}

#ifndef CLSPV_ONLINE_COMPILER
bool save_il_to_file(const std::string& fname, const std::vector<uint8_t>& il) {
    return save_cstring_to_file(fname, reinterpret_cast<const char*>(il.data()),
                                il.size(), std::ios::binary);
}
#endif // CLSPV_ONLINE_COMPILER
#endif // COMPILER_AVAILABLE

struct temp_folder_deletion {
    temp_folder_deletion(const std::string& path) : m_path(path) {}
    ~temp_folder_deletion() {
        if (!config.keep_temporaries && !m_path.empty())
            std::filesystem::remove_all(m_path.c_str());
    }

private:
    std::string m_path;
};

enum class spirv_validation_level
{
    skip,
    warn,
    error,
};

bool validate_binary(spir_binary const& binary,
                     spirv_validation_options const& val_options) {
    spirv_validation_level level = spirv_validation_level::error;
    if (config.spirv_validation.set) {
        if (config.spirv_validation == 0) {
            level = spirv_validation_level::skip;
        } else if (config.spirv_validation == 1) {
            level = spirv_validation_level::warn;
        }
    }

    if (level == spirv_validation_level::skip) {
        cvk_info("Skipping validation of SPIR-V binary.");
        return true;
    }

    if (binary.validate(val_options)) {
        cvk_info("SPIR-V binary is valid.");
        return true;
    }

    if (level == spirv_validation_level::warn) {
        cvk_warn("SPIR-V binary is invalid.");
        return true;
    }

    cvk_error("SPIR-V binary is invalid.");
    return false;
}

const uint32_t clvk_binary_magic =
    0x6B766C63; // "clvk" in ASCII in little-endian
const uint32_t clvk_binary_version = 1;
struct clvk_binary_header {
    uint32_t magic;
    uint32_t version;
    uint32_t binary_type;
};
#define COPY_WORD(dst, src)                                                    \
    do {                                                                       \
        ((unsigned char*)dst)[0] = ((unsigned char*)(src))[0];                 \
        ((unsigned char*)dst)[1] = ((unsigned char*)(src))[1];                 \
        ((unsigned char*)dst)[2] = ((unsigned char*)(src))[2];                 \
        ((unsigned char*)dst)[3] = ((unsigned char*)(src))[3];                 \
    } while (0)

} // namespace

bool cvk_program::read_llvm_bitcode(const unsigned char* src, size_t size) {
    if (size >= 4 &&
        (src[0] == 'B' && src[1] == 'C' && src[2] == 0xc0 && src[3] == 0xde)) {
        m_ir.resize(size);
        memcpy(m_ir.data(), src, size);
        m_dev_status[m_context->device()] = CL_BUILD_SUCCESS;
        return true;
    }
    return false;
}

void cvk_program::write_binary_header(unsigned char* dst) const {
    struct clvk_binary_header* header = (struct clvk_binary_header*)dst;
    COPY_WORD(&header->magic, &clvk_binary_magic);
    COPY_WORD(&header->version, &clvk_binary_version);
    COPY_WORD(&header->binary_type, &m_binary_type);
}

cl_program_binary_type cvk_program::read_binary_header(const unsigned char* src,
                                                       size_t size) {
    struct clvk_binary_header* header = (struct clvk_binary_header*)src;
    if (size < sizeof(header)) {
        return CL_PROGRAM_BINARY_TYPE_NONE;
    }
    uint32_t magic, version, binary_type;
    COPY_WORD(&magic, &header->magic);
    COPY_WORD(&version, &header->version);
    COPY_WORD(&binary_type, &header->binary_type);
    if (magic != clvk_binary_magic) {
        cvk_info_fn("magic not found");
        return CL_PROGRAM_BINARY_TYPE_NONE;
    }
    if (version != clvk_binary_version) {
        cvk_warn_fn("wrong version");
        return CL_PROGRAM_BINARY_TYPE_NONE;
    }
    return binary_type;
}

bool cvk_program::read(const unsigned char* src, size_t size) {
    bool success = false;
    auto binary_type = read_binary_header(src, size);
    // if the binary does not have a clvk binary header, let's try to read
    // it first as a llvm ir buffer, then as a vulkan spirv buffer.
    if (binary_type == CL_PROGRAM_BINARY_TYPE_NONE) {
        cvk_info_fn("no clvk binary header found, looking for llvm bitcode");
        if (read_llvm_bitcode(src, size)) {
            m_binary_type = CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT;
            cvk_info_fn("llvm bitcode compiled object found");
            return true;
        }
        cvk_info_fn("llvm bitcode not found, looking for Vulkan SPIR-V binary");
        if (m_binary.read(src, size)) {
            m_binary_type = CL_PROGRAM_BINARY_TYPE_EXECUTABLE;
            cvk_info_fn("Vulkan SPIR-V binary executable found");
            return true;
        }
        cvk_error_fn("unable to read binary");
        return success;
    }

    auto header_size = sizeof(struct clvk_binary_header);
    src += header_size;
    size -= header_size;

    switch (binary_type) {
    case CL_PROGRAM_BINARY_TYPE_LIBRARY:
    case CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT:
        success = read_llvm_bitcode(src, size);
        break;
    case CL_PROGRAM_BINARY_TYPE_EXECUTABLE:
        success = m_binary.read(src, size);
        break;
    }
    if (success) {
        m_binary_type = binary_type;
    }
    return success;
}

bool cvk_program::write(unsigned char* dst) const {
    write_binary_header(dst);
    dst += sizeof(struct clvk_binary_header);

    switch (m_binary_type) {
    case CL_PROGRAM_BINARY_TYPE_LIBRARY:
    case CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT:
        memcpy(dst, m_ir.data(), m_ir.size());
        return true;
    case CL_PROGRAM_BINARY_TYPE_EXECUTABLE:
        return m_binary.write(dst);
    }
    return false;
}

size_t cvk_program::binary_size() const {
    auto header_size = sizeof(struct clvk_binary_header);
    switch (m_binary_type) {
    case CL_PROGRAM_BINARY_TYPE_LIBRARY:
    case CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT:
        return header_size + m_ir.size();
    case CL_PROGRAM_BINARY_TYPE_EXECUTABLE:
        return header_size + m_binary.size();
    }
    return 0;
}

std::string cvk_program::prepare_build_options(const cvk_device* device) const {
    // Strip off a few options we can't handle
    std::string options;
    if (m_build_options.size() > 0) {
        options += " ";
        options += m_build_options;
    }
    std::vector<std::pair<std::string, std::string>> option_substitutions = {
        // FIXME The 1.2 conformance tests shouldn't pass this option.
        //       It doesn't exist after OpenCL 1.0.
        {"-cl-strict-aliasing", ""},
        // clspv require entrypoint inlining for OpenCL 2.0 and OpenCL 3.0 (for
        // generic addrspace for example).
        {"-cl-std=CL2.0", "-cl-std=CL2.0 -inline-entry-points"},
        {"-cl-std=CL3.0", "-cl-std=CL3.0 -inline-entry-points"},
        {"-create-library", ""},
    };

    for (auto& subst : option_substitutions) {
        size_t loc = options.find(subst.first);
        if (loc != std::string::npos) {
            options.replace(loc, subst.first.length(), subst.second);
        }
    }

    // Check for some options we need and add them if not present.
    std::string necessary_options[] = {
        "-cl-single-precision-constant",
        "-cl-kernel-arg-info",
    };
    for (std::string option : necessary_options) {
        if (options.find(option) == std::string::npos) {
            options += " " + option + " ";
        }
    }

    // The device sets up some compiler options based on its capabilities.
    options += " " + device->get_device_specific_compile_options() + " ";

    // Features
    if (options.find("-cl-std=CL3.0") != std::string::npos) {
        auto features = device->opencl_c_features();
        if (!features.empty()) {
            options += "-enable-feature-macros=";
            for (auto& feature : features) {
                options += feature.name;
                options += ',';
            }
            options.back() = ' '; // replace the final comma
        }
    }

    auto buff_size = m_context->get_printf_buffersize();

    options += " -enable-printf ";
    options += " -printf-buffer-size=" + std::to_string(buff_size) + " ";

#if COMPILER_AVAILABLE
    options += " " + config.clspv_options() + " ";
#endif
    // split options into a vector
    std::istringstream iss(options);
    std::vector<std::string> vector_options;
    std::string token;
    while (std::getline(iss, token, ' ')) {
        vector_options.push_back(token);
    }

    // loop through the options and quote the ones that need it
    std::string quoted_options;
    for (size_t i = 0; i < vector_options.size(); i++) {
        if (vector_options[i].empty()) {
            continue;
        }
        if (vector_options[i].find("-") == 0) {
            quoted_options += vector_options[i];
        } else {
            quoted_options += "\"" + vector_options[i] + "\"";
        }
        quoted_options += " ";
    }

    return quoted_options;
}

cl_int cvk_program::parse_user_spec_constants() {
#if COMPILER_AVAILABLE && ENABLE_SPIRV_IL
#ifndef CLSPV_ONLINE_COMPILER
    // We'll need to go through the whole temp folder rigamarole to query the
    // spec constant info with the command line tool.
    std::filesystem::path tmp_prefix(config.compiler_temp_dir());
    std::filesystem::path tmp_suffix("clvk-XXXXXX");
    std::string tmp_template = (tmp_prefix / tmp_suffix).string();
    const char* tmp = cvk_mkdtemp(tmp_template);
    if (tmp == nullptr) {
        cvk_error_fn("Could not create temporary folder \"%s\"",
                     tmp_template.c_str());
        return CL_INVALID_VALUE;
    }
    std::string tmp_folder = tmp;
    cvk_info("Created temporary folder \"%s\"", tmp_folder.c_str());

    std::string llvmspirv_input_file = tmp_folder + "/source.spv";

    if (!save_il_to_file(llvmspirv_input_file, m_il)) {
        cvk_error_fn("Couldn't save IL to file!");
        return CL_INVALID_VALUE;
    }

    std::string cmd_spv{config.llvmspirv_bin()};
    cmd_spv += " --spec-const-info ";
    cmd_spv += llvmspirv_input_file;

    std::string output = "";
    cvk_exec(cmd_spv, &output);
    auto output_stream = std::istringstream(output);

    for (std::string line; std::getline(output_stream, line);) {
        if (line.find("Spec const id") == std::string::npos) {
            continue;
        }

        auto delim = line.find(",");
        auto id_string = line.substr(0, delim);
        line.erase(0, delim + 1);
        id_string = id_string.substr(id_string.find("=") + 1);
        auto id = static_cast<uint32_t>(atoi(id_string.c_str()));

        delim = line.find(",");
        auto size_string = line.substr(0, delim);
        line.erase(0, delim + 1);
        size_string = size_string.substr(size_string.find("=") + 1);
        auto size = static_cast<uint32_t>(atoi(size_string.c_str()));

        // We need to consume the "=" and the " " here since we aren't
        // converting the value from a string.
        auto type_string = line.substr(line.find("=") + 2);
        m_user_spec_constants.emplace(
            id, user_spec_constant_data{type_string, size});
    }
    std::filesystem::remove_all(tmp_folder.c_str());
    return CL_SUCCESS;
#else
    auto m_il_start = reinterpret_cast<const unsigned char*>(m_il.data());
    membuf m_il_buf(m_il_start, m_il_start + m_il.size());
    std::istream m_il_stream(&m_il_buf);
    SPIRV::TranslatorOpts translator_opts;
    // We don't need llvm-spirv to validate extensions for us.
    translator_opts.enableAllExtensions();
    static std::mutex llvmspirv_compile_mutex;
    std::lock_guard<std::mutex> llvmspirv_compile_lock(llvmspirv_compile_mutex);

    std::vector<llvm::SpecConstInfoTy> spec_const_info;

    if (!getSpecConstInfo(m_il_stream, spec_const_info)) {
        cvk_error_fn("Failed to parse spec constants");
        return CL_INVALID_VALUE;
    }

    for (const auto& spec_const : spec_const_info) {
        m_user_spec_constants.emplace(
            spec_const.ID,
            user_spec_constant_data{spec_const.Type, spec_const.Size});
    }
    return CL_SUCCESS;
#endif // CLSPV_ONLINE_COMPILER
#else
#if !COMPILER_AVAILABLE
    cvk_error_fn("Could not parse user spec constants because clvk has been "
                 "built with CLVK_COMPILER_AVAILABLE=OFF");
#elif !ENABLE_SPIRV_IL
    cvk_error_fn("Could not parse user spec constants because clvk has been "
                 "built with CLVK_ENABLE_SPIRV_IL=OFF");
#endif
    return CL_INVALID_OPERATION;
#endif // COMPILER_AVAILABLE
}

#if COMPILER_AVAILABLE
#ifndef CLSPV_ONLINE_COMPILER
cl_build_status cvk_program::do_build_inner_offline(bool build_to_ir,
                                                    bool build_from_il,
                                                    std::string& build_options,
                                                    std::string& tmp_folder) {
    TRACE_FUNCTION("build_to_ir", build_to_ir, "build_from_il", build_from_il,
                   "build_options", TRACE_STRING(build_options.c_str()));
    // Compose clspv command-line
    std::string cmd{config.clspv_path};
    cmd += " ";

    std::string clspv_input_file{tmp_folder + "/source"};
    // Save input program to a file
    if (build_from_il) {
#ifndef ENABLE_SPIRV_IL
        cvk_error_fn("Could not build from il because clvk has been built with "
                     "CLVK_ENABLE_SPIRV_IL=OFF");
        return CL_BUILD_ERROR;
#else  // ENABLE_SPIRV_IL
        std::string llvmspirv_input_file{tmp_folder + "/source.spv"};
        clspv_input_file += ".bc";
        if (!save_il_to_file(llvmspirv_input_file, m_il)) {
            cvk_error_fn("Couldn't save IL to file!");
            return CL_BUILD_ERROR;
        }
        // Compose llvm-spirv command-line
        std::string cmd_spv{config.llvmspirv_bin};

        if (!m_user_spec_constants.empty()) {
            std::string spec_constant_flag = " --spec-const=";
            for (const auto& spec_const : m_user_spec_constants) {
                if (!spec_const.second.set) {
                    continue;
                }
                const auto& type_string = spec_const.second.type;
                spec_constant_flag +=
                    std::to_string(spec_const.first) + ":" + type_string + ":";

                if (type_string.find("i32") != std::string::npos) {
                    spec_constant_flag +=
                        std::to_string(spec_const.second.data.i32);
                } else if (type_string.find("i16") != std::string::npos) {
                    spec_constant_flag +=
                        std::to_string(spec_const.second.data.i16);
                } else if (type_string.find("i8") != std::string::npos ||
                           type_string.find("i1") != std::string::npos) {
                    spec_constant_flag +=
                        std::to_string(spec_const.second.data.i8);
                } else if (type_string.find("i64") != std::string::npos) {
                    spec_constant_flag +=
                        std::to_string(spec_const.second.data.i64);
                } else if (type_string.find("f16") != std::string::npos) {
                    // At most we should need seven (0xFFFF\0)
                    char buf[7];
                    std::snprintf(buf, 7, "0x%04X", spec_const.second.data.i16);
                    spec_constant_flag += std::string(buf);
                } else if (type_string.find("f32") != std::string::npos) {
                    float spec_value;
                    std::memcpy(&spec_value, &spec_const.second.data.i32,
                                spec_const.second.size);
                    spec_constant_flag += std::to_string(spec_value);
                } else if (type_string.find("f64") != std::string::npos) {
                    double spec_value;
                    std::memcpy(&spec_value, &spec_const.second.data.i64,
                                spec_const.second.size);
                    spec_constant_flag += std::to_string(spec_value);
                }
                spec_constant_flag += " ";
            }
            cmd_spv += spec_constant_flag;
        }

        cmd_spv += " -r ";
        cmd_spv += " -o ";
        cmd_spv += clspv_input_file;
        cmd_spv += " ";
        cmd_spv += llvmspirv_input_file;

        // Call the translator
        int status = cvk_exec(cmd_spv);

        if (status != 0) {
            cvk_error_fn("failed to translate SPIR-V to LLVM IR");
            return CL_BUILD_ERROR;
        }

        cmd += clspv_input_file;
        cmd += " ";
#endif // ENABLE_SPIRV_IL
    } else if (m_operation == build_operation::link) {
        for (auto input_program : m_input_programs) {
            if (input_program->m_binary_type !=
                    CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT &&
                input_program->m_binary_type !=
                    CL_PROGRAM_BINARY_TYPE_LIBRARY) {
                return CL_BUILD_ERROR;
            }
            std::string input_file = clspv_input_file + "_" +
                                     std::to_string((uintptr_t)input_program) +
                                     ".bc";
            if (!save_il_to_file(input_file, input_program->m_ir)) {
                cvk_error_fn("Couldn't save source to file!");
                return CL_BUILD_ERROR;
            }
            cmd += input_file;
            cmd += " ";
        }
    } else {
        if (m_source.empty() && !m_ir.empty()) {
            clspv_input_file += ".bc";
            if (!save_il_to_file(clspv_input_file, m_ir)) {
                cvk_error_fn("Couldn't save source to file!");
                return CL_BUILD_ERROR;
            }
            cmd += clspv_input_file;
            cmd += " ";
        } else {
            clspv_input_file += ".cl";
            if (!save_string_to_file(clspv_input_file, m_source)) {
                cvk_error_fn("Couldn't save source to file!");
                return CL_BUILD_ERROR;
            }
            cmd += clspv_input_file;
            cmd += " ";
        }
    }

    std::string clspv_output_file{tmp_folder + "/compiled"};
    if (build_to_ir) {
        clspv_output_file += ".bc";
    } else {
        clspv_output_file += ".spv";
    }

    cmd += build_options;
    cmd += " -o ";
    cmd += clspv_output_file;

    // Call clspv
    int status = cvk_exec(cmd, &m_build_log);
    if (status != 0) {
        cvk_error_fn("failed to compile the program");
        cvk_debug_fn("%s", m_build_log.c_str());
        return CL_BUILD_ERROR;
    }

    // Load output from clspv
    if (build_to_ir) {
        std::ifstream stream(clspv_output_file,
                             std::ios::in | std::ios::binary);
        m_ir.assign((std::istreambuf_iterator<char>(stream)),
                    std::istreambuf_iterator<char>());
        if (!stream.good()) {
            return CL_BUILD_ERROR;
        }
    } else {
        const char* filename = clspv_output_file.c_str();
        if (!m_binary.load(filename)) {
            cvk_error("Could not load SPIR-V binary from \"%s\"", filename);
            return CL_BUILD_ERROR;
        }
    }

    cvk_info("Loaded %s binary from \"%s\", size = %zu %s",
             build_to_ir ? "IR" : "SPIR-V", clspv_output_file.c_str(),
             build_to_ir ? m_ir.size() : m_binary.code().size(),
             build_to_ir ? "bytes" : "words");

    return CL_BUILD_SUCCESS;
}

#else // #ifndef CLSPV_ONLINE_COMPILER

cl_build_status cvk_program::do_build_inner_online(bool build_to_ir,
                                                   bool build_from_il,
                                                   std::string& build_options) {
    TRACE_FUNCTION("build_to_ir", build_to_ir, "build_from_il", build_from_il,
                   "build_options", TRACE_STRING(build_options.c_str()));
    cvk_info_fn("build_from_il %u - build_to_ir %u", build_from_il,
                build_to_ir);
    if (build_from_il) {
#ifndef ENABLE_SPIRV_IL
        cvk_error_fn("Could not build from il because clvk has been built with "
                     "CLVK_ENABLE_SPIRV_IL=OFF");
        return CL_BUILD_ERROR;
#else  // ENABLE_SPIRV_IL
        llvm::LLVMContext llvm_context;
        llvm::Module* llvm_module;
        std::string err;
        auto m_il_start = reinterpret_cast<const unsigned char*>(m_il.data());
        membuf m_il_buf(m_il_start, m_il_start + m_il.size());
        std::istream m_il_stream(&m_il_buf);
        SPIRV::TranslatorOpts translator_opts;
        // We don't need llvm-spirv to validate extensions for us.
        translator_opts.enableAllExtensions();

        for (const auto& spec_const : m_user_spec_constants) {
            if (!spec_const.second.set) {
                continue;
            }
            uint64_t spec_const_value = 0;
            if (spec_const.second.type == "i1" ||
                spec_const.second.type == "i8") {
                spec_const_value = spec_const.second.data.i8;
            } else if (spec_const.second.type == "i16" ||
                       spec_const.second.type == "f16") {
                spec_const_value = spec_const.second.data.i16;
            } else if (spec_const.second.type == "i32" ||
                       spec_const.second.type == "f32") {
                spec_const_value = spec_const.second.data.i32;
            } else if (spec_const.second.type == "i64" ||
                       spec_const.second.type == "f64") {
                spec_const_value = spec_const.second.data.i64;
            }
            translator_opts.setSpecConst(spec_const.first, spec_const_value);
        }

        // llvm-spirv is based on LLVM. LLVM options parsing is done using
        // global variable that are not thread safe. Thus, we need to lock call
        // to llvm-spirv in order to ensure a thread safe execution.
        {
            static std::mutex llvmspirv_compile_mutex;
            std::lock_guard<std::mutex> llvmspirv_compile_lock(
                llvmspirv_compile_mutex);
            std::vector<const char*> llvmArgv{
                "llvm-spirv(online)",
            };
            llvm::cl::ResetAllOptionOccurrences();
            llvm::cl::ParseCommandLineOptions(llvmArgv.size(), llvmArgv.data());
            if (!llvm::readSpirv(llvm_context, translator_opts, m_il_stream,
                                 llvm_module, err)) {
                cvk_error_fn("Fails to load SPIR-V as LLVM Module: %s",
                             err.c_str());
                return CL_BUILD_ERROR;
            }
        }

        m_source.clear();
        llvm::raw_string_ostream spirv_stream(m_source);
        llvm::WriteBitcodeToFile(*llvm_module, spirv_stream);
#endif // ENABLE_SPIRV_IL
    }
    cvk_info("About to compile \"%s\"", build_options.c_str());
    int status;
    // clspv is based on LLVM. LLVM options parsing is done using global
    // variable that are not thread safe. Thus, we need to lock call to clspv in
    // order to ensure a thread safe execution.
    {
        static std::mutex clspv_compile_mutex;
        std::lock_guard<std::mutex> clspv_compile_lock(clspv_compile_mutex);
        std::vector<std::string> programs;
        if (m_operation == build_operation::link) {
            for (auto input_program : m_input_programs) {
                if (input_program->m_binary_type !=
                        CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT &&
                    input_program->m_binary_type !=
                        CL_PROGRAM_BINARY_TYPE_LIBRARY) {
                    return CL_BUILD_ERROR;
                }
                programs.emplace_back(std::string{input_program->m_ir.begin(),
                                                  input_program->m_ir.end()});
            }
        } else {
            if (m_source.empty() && !m_ir.empty()) {
                programs.emplace_back(std::string{m_ir.begin(), m_ir.end()});
            } else {
                programs.emplace_back(m_source);
            }
        }
        m_build_log.clear();
        if (build_to_ir) {
            std::vector<uint32_t> ir;
            status = clspv::CompileFromSourcesString(programs, build_options,
                                                     &ir, &m_build_log);
            m_ir.clear();
            auto size = ir.size() * sizeof(uint32_t);
            m_ir.resize(size);
            memcpy(m_ir.data(), ir.data(), size);
        } else {
            status = clspv::CompileFromSourcesString(
                programs, build_options, m_binary.raw_binary(), &m_build_log);
        }
    }
    if (status != 0) {
        cvk_error_fn("failed to compile the program");
        cvk_debug_fn("%s", m_build_log.c_str());
        return CL_BUILD_ERROR;
    }
    return CL_BUILD_SUCCESS;
}

#endif // #ifndef CLSPV_ONLINE_COMPILER
#endif // #if COMPILER_AVAILABLE

cl_build_status cvk_program::do_build_inner(const cvk_device* device) {
#if !COMPILER_AVAILABLE
    UNUSED(device);
#else
    // m_il and m_source cannot be set together.
    // They can both be empty when loading from binary.
    CVK_ASSERT(m_il.empty() || m_source.empty());

    bool build_from_il =
        m_il.size() > 0 && m_operation != build_operation::link;
    bool use_tmp_folder = true;
#ifdef CLSPV_ONLINE_COMPILER
    use_tmp_folder =
        m_operation == build_operation::compile && m_num_input_programs > 0;
#endif

    std::string tmp_folder;
    if (use_tmp_folder) {
        // Create temporary folder
        std::filesystem::path tmp_prefix(config.compiler_temp_dir());
        std::filesystem::path tmp_suffix("clvk-XXXXXX");
        std::string tmp_template = (tmp_prefix / tmp_suffix).string();
        const char* tmp = cvk_mkdtemp(tmp_template);
        if (tmp == nullptr) {
            cvk_error_fn("Could not create temporary folder \"%s\"",
                         tmp_template.c_str());
            return CL_BUILD_ERROR;
        }
        tmp_folder = tmp;
        cvk_info("Created temporary folder \"%s\"", tmp_folder.c_str());
    }
    temp_folder_deletion temp(tmp_folder);

    // Prepare build options
    bool create_library =
        m_build_options.find("create-library") != std::string::npos;
    auto build_options = prepare_build_options(device);

    // Add options to specify input/output types
    if (m_source.empty() || m_operation == build_operation::link) {
        build_options += " -x ir ";
    }
    bool build_to_ir =
        m_operation == build_operation::compile || create_library;
    if (build_to_ir) {
        build_options += " --output-format=bc ";
    }

    // Save headers
    if (use_tmp_folder && m_operation == build_operation::compile) {
        build_options += "-I" + tmp_folder;
        for (cl_uint i = 0; i < m_num_input_programs; i++) {
            std::string fname{tmp_folder + "/" + m_header_include_names[i]};
            if (!save_string_to_file(fname, m_input_programs[i]->source())) {
                cvk_error_fn("Couldn't save header to file!");
                return CL_BUILD_ERROR;
            }
        }
    }

    cl_build_status build_status;
#ifdef CLSPV_ONLINE_COMPILER
    build_status =
        do_build_inner_online(build_to_ir, build_from_il, build_options);
#else
    build_status = do_build_inner_offline(build_to_ir, build_from_il,
                                          build_options, tmp_folder);
#endif // CLSPV_ONLINE_COMPILER
    if (build_status != CL_BUILD_SUCCESS) {
        return build_status;
    }

    // Select operation
    if (m_operation == build_operation::compile) {
        m_binary_type = CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT;
    } else if (m_operation == build_operation::link && create_library) {
        m_binary_type = CL_PROGRAM_BINARY_TYPE_LIBRARY;
    } else {
        m_binary_type = CL_PROGRAM_BINARY_TYPE_EXECUTABLE;
    }

#endif // #if !COMPILER_AVAILABLE
    return CL_BUILD_SUCCESS;
}

void cvk_program::prepare_push_constant_range() {
    auto& pcs = m_binary.push_constants();

    uint32_t min_offset = UINT32_MAX;
    uint32_t max_offset = 0, max_offset_size = 0;

    for (auto& pc_pcd : pcs) {
        auto pcd = pc_pcd.second;
        min_offset = std::min(min_offset, pcd.offset);
        if (pcd.offset >= max_offset) {
            max_offset = pcd.offset;
            max_offset_size = pcd.size;
        }
    }

    m_push_constant_range = {VK_SHADER_STAGE_COMPUTE_BIT, min_offset,
                             max_offset + max_offset_size};
}

bool cvk_program::check_capabilities(const cvk_device* device) {
    // Get list of required SPIR-V capabilities.
    std::vector<spv::Capability> capabilities;
    if (!m_binary.get_capabilities(capabilities)) {
        cvk_error("Failed to get required SPIR-V capabilities.");
        return false;
    }

    // Check that each required capability is supported by the device.
    for (auto c : capabilities) {
        cvk_info_fn("Program requires SPIR-V capability %d (%s).", c,
                    spirv_capability_to_string(c));
        if (!device->supports_capability(c)
#ifdef CLVK_UNIT_TESTING_ENABLED
            || config.force_check_capabilities_error()
#endif
        ) {
            std::stringstream error_message;
            error_message << "Device does not support SPIR-V capability " << c
                          << " (" << spirv_capability_to_string(c) << ").";
            cvk_error_fn("%s", error_message.str().c_str());
            m_build_log += error_message.str();
            return false;
        }
    }
    return true;
}

void cvk_program::do_build() {
    // Destroy entry points from previous build
    m_entry_points.clear();

    auto device = m_context->device();

    if (m_operation != build_operation::build_binary) {
        cl_build_status status = do_build_inner(device);

        if ((m_binary_type != CL_PROGRAM_BINARY_TYPE_EXECUTABLE) ||
            (status != CL_BUILD_SUCCESS)) {
            complete_operation(device, status);
            return;
        }
    }

    // Load descriptor map
    if (!m_binary.load_descriptor_map()) {
        cvk_error("Could not load descriptor map for SPIR-V binary.");
        complete_operation(device, CL_BUILD_ERROR);
        return;
    }

    if (!create_module_constant_data_buffer()) {
        complete_operation(device, CL_BUILD_ERROR);
        return;
    }

    prepare_push_constant_range();

    bool cache_hit =
        device->get_pipeline_cache(m_binary.code(), m_pipeline_cache);
    if (m_pipeline_cache == VK_NULL_HANDLE) {
        complete_operation(device, CL_BUILD_ERROR);
        return;
    }

    if (!cache_hit) {
        // Validate
        // TODO validate with different rules depending on the binary type
        if (m_binary_type == CL_PROGRAM_BINARY_TYPE_EXECUTABLE) {
            spirv_validation_options validation_options{};
            validation_options.uniform_buffer_std_layout =
                m_context->device()->supports_ubo_stdlayout();
            if (!validate_binary(m_binary, validation_options)) {
                complete_operation(device, CL_BUILD_ERROR);
                return;
            }
        }
    }

    // Check capabilities against the device.
    if ((m_binary_type == CL_PROGRAM_BINARY_TYPE_EXECUTABLE) &&
        !config.skip_spirv_capability_check && !check_capabilities(device)) {
        cvk_error("Missing support for required SPIR-V capabilities.");
        complete_operation(device, CL_BUILD_ERROR);
        return;
    }

    // Create literal samplers
    for (auto const& desc : literal_sampler_descs()) {
        auto sampler =
            cvk_sampler::create(context(), desc.normalized_coords,
                                desc.addressing_mode, desc.filter_mode);
        if (sampler == nullptr) {
            complete_operation(device, CL_BUILD_ERROR);
            return;
        }
        m_literal_samplers.emplace_back(sampler);
    }

    // Strip the reflection information if non-semantic info is not supported
    // by the Vulkan implementation. This stripped binary is stored separately
    // from |m_binary| because clvk needs to be able to provide the binary with
    // reflection information for clGetProgramInfo.
    const uint32_t* spir_data = m_binary.spir_data();
    size_t spir_size = m_binary.spir_size();
    const bool should_strip_reflection =
        !device->is_vulkan_extension_enabled(
            VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME)
#ifdef USING_SWIFTSHADER
        || true
#endif
        ;
    if (should_strip_reflection) {
        if (!m_binary.strip_reflection(&m_stripped_binary)) {
            cvk_error_fn("couldn't strip reflection from SPIR-V module");
            complete_operation(device, CL_BUILD_ERROR);
            return;
        }
        spir_data = m_stripped_binary.data();
        spir_size = m_stripped_binary.size() * sizeof(uint32_t);
    }

    // Create a shader module
    VkDevice dev = device->vulkan_device();

    VkShaderModuleCreateInfo moduleCreateInfo = {
        VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, // sType
        nullptr,                                     // pNext
        0,                                           // flags
        spir_size,                                   // codeSize
        spir_data                                    // pCode
    };

    VkResult res =
        vkCreateShaderModule(dev, &moduleCreateInfo, nullptr, &m_shader_module);

    if (res != VK_SUCCESS) {
        cvk_error("vkCreateShaderModule returned %d", res);
        complete_operation(device, CL_BUILD_ERROR);
        return;
    }

    complete_operation(device, CL_BUILD_SUCCESS);
}

cl_int cvk_program::build(build_operation operation, cl_uint num_devices,
                          const cl_device_id* device_list, const char* options,
                          cl_uint num_input_programs,
                          const cl_program* input_programs,
                          const char** header_include_names,
                          cvk_program_callback cb, void* data) {
    std::lock_guard<std::mutex> lock(m_lock);

    // Check if there is already a build in progress
    // TODO: Allow concurrent builds targeting different devices
    if (std::count_if(m_dev_status.begin(), m_dev_status.end(),
                      [](auto& status) {
                          return status.second == CL_BUILD_IN_PROGRESS;
                      })) {
        return CL_INVALID_OPERATION;
    }

    retain();

    for (cl_uint i = 0; i < num_input_programs; i++) {
        cvk_program* iprog =
            const_cast<cvk_program*>(icd_downcast(input_programs[i]));
        iprog->retain();
        m_input_programs.push_back(iprog);
        if (header_include_names != nullptr) {
            m_header_include_names.push_back(header_include_names[i]);
        }
    }

    // Mark build in-progress and save devices
    if (num_devices == 0) {
        m_num_devices = 1u;
        m_dev_status[m_context->device()] = CL_BUILD_IN_PROGRESS;
    } else {
        m_num_devices = num_devices;
        for (cl_uint i = 0; i < num_devices; i++) {
            m_dev_status[icd_downcast(device_list[i])] = CL_BUILD_IN_PROGRESS;
        }
    }

    if (options != nullptr) {
        m_build_options = options;
    }
    m_num_input_programs = num_input_programs;
    m_operation = operation;
    m_operation_callback = cb;
    m_operation_callback_data = data;

    cl_int ret = CL_SUCCESS;
    bool build_in_separate_thread = config.build_in_separate_thread() || cb;
    bool wait_for_completion = !cb;
    if (build_in_separate_thread) {
        // Kick off build
        m_thread = std::make_unique<std::thread>(
            &cvk_program::do_build_in_separate_thread, this);
        if (!wait_for_completion) {
            m_thread->detach();
        }
    } else {
        do_build();
    }

    if (wait_for_completion) {
        if (build_in_separate_thread) {
            CVK_ASSERT(m_thread->joinable());
            m_thread->join();
        }
        if (build_status() != CL_BUILD_SUCCESS) {
            switch (operation) {
            case build_operation::link:
                ret = CL_LINK_PROGRAM_FAILURE;
                break;
            case build_operation::build:
            case build_operation::build_binary:
                ret = CL_BUILD_PROGRAM_FAILURE;
                break;
            case build_operation::compile:
                ret = CL_COMPILE_PROGRAM_FAILURE;
                break;
            }
            CVK_ASSERT(ret != CL_SUCCESS);
        }
    }
    return ret;
}

cvk_entry_point::cvk_entry_point(cvk_device* dev, cvk_program* program,
                                 const std::string& name)
    : m_device(dev), m_context(program->context()), m_program(program),
      m_name(name), m_pod_descriptor_type(VK_DESCRIPTOR_TYPE_MAX_ENUM),
      m_pod_buffer_size(0u), m_has_pod_arguments(false),
      m_has_pod_buffer_arguments(false), m_sampler_metadata(nullptr),
      m_image_metadata(nullptr), m_descriptor_pool(VK_NULL_HANDLE),
      m_pipeline_layout(VK_NULL_HANDLE), m_nb_descriptor_set_allocated(0),
      m_first_allocation_failure(true) {
    TRACE_CNT_VAR_INIT(descriptor_set_allocated_counter,
                       "clvk-entry_point_" + std::to_string((uintptr_t)this),
                       dev->track());
    TRACE_CNT(descriptor_set_allocated_counter, 0);
}

std::shared_ptr<cvk_entry_point>
cvk_program::get_entry_point(std::string& name, cl_int* errcode_ret) {
    std::lock_guard<std::mutex> lock(m_lock);

    // Check for existing entry point in cache
    if (m_entry_points.count(name)) {
        *errcode_ret = CL_SUCCESS;
        return m_entry_points.at(name);
    }

    // Create and initialize entry point
    std::shared_ptr<cvk_entry_point> entry_point =
        std::make_shared<cvk_entry_point>(m_context->device(), this, name);
    *errcode_ret = entry_point->init();
    if (*errcode_ret != CL_SUCCESS) {
        return nullptr;
    }

    // Add to cache for reuse by other kernels
    m_entry_points.insert({name, entry_point});

    return entry_point;
}

bool cvk_entry_point::build_descriptor_set_layout(
    const std::vector<VkDescriptorSetLayoutBinding>& bindings) {
    VkDescriptorSetLayoutCreateInfo createInfo = {
        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr,
        0,                                      // flags
        static_cast<uint32_t>(bindings.size()), // bindingCount
        bindings.data()                         // pBindings
    };

    VkResult res;
    if (bindings.size() > 0) {
        VkDescriptorSetLayout setLayout;
        res = vkCreateDescriptorSetLayout(m_device->vulkan_device(),
                                          &createInfo, 0, &setLayout);
        if (res != VK_SUCCESS) {
            cvk_error("Could not create descriptor set layout");
            return false;
        }
        m_descriptor_set_layouts.push_back(setLayout);
    }

    return true;
}

bool cvk_entry_point::build_descriptor_sets_layout_bindings_for_arguments(
    binding_stat_map& smap, uint32_t& num_resource_slots) {
    bool pod_found = false;

    uint32_t highest_binding = 0;

    std::vector<VkDescriptorSetLayoutBinding> layoutBindings;
    for (auto& arg : m_args) {
        VkDescriptorType dt = VK_DESCRIPTOR_TYPE_MAX_ENUM;

        switch (arg.kind) {
        case kernel_argument_kind::buffer:
            dt = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
            break;
        case kernel_argument_kind::buffer_ubo:
            dt = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
            break;
        case kernel_argument_kind::sampled_image:
            dt = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
            break;
        case kernel_argument_kind::storage_image:
            dt = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
            break;
        case kernel_argument_kind::storage_texel_buffer:
            dt = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
            break;
        case kernel_argument_kind::uniform_texel_buffer:
            dt = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
            break;
        case kernel_argument_kind::sampler:
            dt = VK_DESCRIPTOR_TYPE_SAMPLER;
            break;
        case kernel_argument_kind::local:
            continue;
        case kernel_argument_kind::pod:
        case kernel_argument_kind::pod_ubo:
        case kernel_argument_kind::pointer_ubo:
            if (!pod_found) {
                if (arg.kind == kernel_argument_kind::pod) {
                    dt = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
                } else if (arg.kind == kernel_argument_kind::pod_ubo ||
                           arg.kind == kernel_argument_kind::pointer_ubo) {
                    dt = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
                }

                m_pod_descriptor_type = dt;

                pod_found = true;
            } else {
                continue;
            }
            break;
        case kernel_argument_kind::pod_pushconstant:
        case kernel_argument_kind::pointer_pushconstant:
        case kernel_argument_kind::unused:
            continue;
        }

        VkDescriptorSetLayoutBinding binding = {
            arg.binding,                 // binding
            dt,                          // descriptorType
            1,                           // decriptorCount
            VK_SHADER_STAGE_COMPUTE_BIT, // stageFlags
            nullptr                      // pImmutableSamplers
        };

        highest_binding = std::max(arg.binding, highest_binding);

        layoutBindings.push_back(binding);
        smap[binding.descriptorType]++;
    }

    num_resource_slots = highest_binding + 1;

    if (!build_descriptor_set_layout(layoutBindings)) {
        return false;
    }

    return true;
}

bool cvk_entry_point::
    build_descriptor_sets_layout_bindings_for_literal_samplers(
        binding_stat_map& smap) {

    std::vector<VkDescriptorSetLayoutBinding> layoutBindings;
    for (auto& desc : m_program->literal_sampler_descs()) {
        VkDescriptorSetLayoutBinding binding = {
            desc.binding,                // binding
            VK_DESCRIPTOR_TYPE_SAMPLER,  // descriptorType
            1,                           // decriptorCount
            VK_SHADER_STAGE_COMPUTE_BIT, // stageFlags
            nullptr                      // pImmutableSamplers
        };
        layoutBindings.push_back(binding);
        smap[binding.descriptorType]++;
    }

    if (!build_descriptor_set_layout(layoutBindings)) {
        return false;
    }

    return true;
}

bool cvk_entry_point::
    build_descriptor_sets_layout_bindings_for_program_scope_buffers(
        binding_stat_map& smap) {

    std::vector<VkDescriptorSetLayoutBinding> layoutBindings;
    if (m_program->module_constant_data_buffer() != nullptr) {
        auto info = m_program->module_constant_data_buffer_info();
        // If the program scope buffer isn't passed as a storage buffer (i.e.
        // it is passed a pointer push constant), there is nothing to bind here
        if (info->type != module_buffer_type::storage_buffer) {
            return true;
        }
        VkDescriptorSetLayoutBinding binding = {
            info->binding,                     // binding
            VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
            1,                                 // decriptorCount
            VK_SHADER_STAGE_COMPUTE_BIT,       // stageFlags
            nullptr                            // pImmutableSamplers
        };
        layoutBindings.push_back(binding);
        smap[binding.descriptorType]++;
    }

    if (!build_descriptor_set_layout(layoutBindings)) {
        return false;
    }

    return true;
}

bool cvk_entry_point::build_descriptor_sets_layout_bindings_for_printf_buffer(
    binding_stat_map& smap) {
    std::vector<VkDescriptorSetLayoutBinding> layoutBindings;
    if (m_program->printf_buffer_info().size > 0 && (uses_printf())) {
        auto info = m_program->printf_buffer_info();
        if (info.type != module_buffer_type::storage_buffer) {
            return true;
        }
        VkDescriptorSetLayoutBinding binding = {
            info.binding,                      // binding
            VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
            1,                                 // decriptorCount
            VK_SHADER_STAGE_COMPUTE_BIT,       // stageFlags
            nullptr                            // pImmutableSamplers
        };
        layoutBindings.push_back(binding);
        smap[binding.descriptorType]++;
    }

    if (!build_descriptor_set_layout(layoutBindings)) {
        return false;
    }

    return true;
}

cl_int cvk_entry_point::init() {
    VkResult res;

    // Get the image metadata for the this entry point
    if (auto* md = m_program->image_metadata(m_name)) {
        m_image_metadata = md;
    }

    // Get the sampler metadata for this entry point
    if (auto* md = m_program->sampler_metadata(m_name)) {
        m_sampler_metadata = md;
    }

    // Get a pointer to the arguments from the program
    auto args = m_program->args_for_kernel(m_name);

    if (args == nullptr) {
        cvk_error("Kernel %s doesn't exist in program", m_name.c_str());
        return CL_INVALID_KERNEL_NAME;
    }

    // Store a sorted copy of the arguments
    m_args = *args;
    std::sort(
        m_args.begin(), m_args.end(),
        [](kernel_argument a, kernel_argument b) { return a.pos < b.pos; });

    // Create Descriptor Sets Layout
    std::unordered_map<VkDescriptorType, uint32_t> bindingTypes;
    if (!build_descriptor_sets_layout_bindings_for_literal_samplers(
            bindingTypes)) {
        return CL_INVALID_VALUE;
    }
    if (!build_descriptor_sets_layout_bindings_for_arguments(
            bindingTypes, m_num_resource_slots)) {
        return CL_INVALID_VALUE;
    }
    if (!build_descriptor_sets_layout_bindings_for_program_scope_buffers(
            bindingTypes)) {
        return CL_INVALID_VALUE;
    }
    if (!build_descriptor_sets_layout_bindings_for_printf_buffer(
            bindingTypes)) {
        return CL_INVALID_VALUE;
    }

    // Do we have POD arguments?
    for (auto& arg : m_args) {
        if (arg.is_pod()) {
            m_has_pod_arguments = true;
            if (arg.is_pod_buffer()) {
                m_has_pod_buffer_arguments = true;
            }
        }
    }

    // Calculate POD buffer size and update the push constant range.
    VkPushConstantRange push_constant_range = m_program->push_constant_range();
    if (m_has_pod_arguments) {
        // Check we know the POD buffer's descriptor type
        if (m_has_pod_buffer_arguments &&
            m_pod_descriptor_type == VK_DESCRIPTOR_TYPE_MAX_ENUM) {
            return CL_INVALID_PROGRAM;
        }

        // Find how big the POD buffer should be
        uint32_t max_offset = 0;
        uint32_t max_offset_arg_size = 0;

        for (auto& arg : m_args) {
            if (arg.is_pod()) {
                if (arg.offset >= max_offset) {
                    max_offset = arg.offset;
                    max_offset_arg_size = arg.size;
                }
                if (!arg.is_pod_buffer()) {
                    if (arg.offset < push_constant_range.offset) {
                        push_constant_range.offset = arg.offset;
                    }

                    if (arg.offset + arg.size >
                        push_constant_range.offset + push_constant_range.size) {
                        push_constant_range.size =
                            arg.offset + arg.size - push_constant_range.offset;
                    }
                }
            }
        }

        m_pod_buffer_size = max_offset + max_offset_arg_size;
        m_pod_buffer_size = round_up(m_pod_buffer_size, 4);
    }

    // Take the size of image & sampler metadata into account for the pod buffer
    // size
    {
        uint32_t max_offset = 0;
        if (m_image_metadata) {
            // Find how big the POD buffer should be
            for (const auto& md : *m_image_metadata) {
                auto order_offset = md.second.order_offset;
                auto data_type_offset = md.second.data_type_offset;
                if (md.second.has_valid_order()) {
                    max_offset = std::max(order_offset, max_offset);
                    push_constant_range.offset =
                        std::min(order_offset, push_constant_range.offset);
                    if (order_offset + sizeof(uint32_t) >
                        push_constant_range.offset + push_constant_range.size) {
                        push_constant_range.size = order_offset +
                                                   sizeof(uint32_t) -
                                                   push_constant_range.offset;
                    }
                }
                if (md.second.has_valid_data_type()) {
                    max_offset = std::max(data_type_offset, max_offset);
                    push_constant_range.offset =
                        std::min(data_type_offset, push_constant_range.offset);
                    if (data_type_offset + sizeof(uint32_t) >
                        push_constant_range.offset + push_constant_range.size) {
                        push_constant_range.size = data_type_offset +
                                                   sizeof(uint32_t) -
                                                   push_constant_range.offset;
                    }
                }
            }
        }
        if (m_sampler_metadata) {
            for (const auto& md : *m_sampler_metadata) {
                auto offset = md.second;
                max_offset = std::max(offset, max_offset);
                push_constant_range.offset =
                    std::min(offset, push_constant_range.offset);
                if (offset + sizeof(uint32_t) >
                    push_constant_range.offset + push_constant_range.size) {
                    push_constant_range.size =
                        offset + sizeof(uint32_t) - push_constant_range.offset;
                }
            }
        }
        if (max_offset + sizeof(uint32_t) > m_pod_buffer_size) {
            m_pod_buffer_size = round_up(max_offset + sizeof(uint32_t), 4);
        }
    }

    // Don't pass the range at pipeline layout creation time if no push
    // constants are used
    uint32_t num_push_constant_ranges = 1;
    if (push_constant_range.offset == UINT32_MAX) {
        num_push_constant_ranges = 0;
    }

    // The size of the range must be a multiple of 4, round up to guarantee this
    push_constant_range.size = round_up(push_constant_range.size, 4);

    // Its offset must be a multiple of 4, round down to guarantee this
    push_constant_range.offset &= ~0x3U;

    if (push_constant_range.size >
        m_context->device()->vulkan_max_push_constants_size()) {
        cvk_error("Not enough space for push constants");
        return CL_INVALID_VALUE;
    }

    // Create pipeline layout
    cvk_debug("about to create pipeline layout, number of descriptor set "
              "layouts: %zu",
              m_descriptor_set_layouts.size());

    VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
        VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
        0,
        0,
        static_cast<uint32_t>(m_descriptor_set_layouts.size()),
        m_descriptor_set_layouts.data(),
        num_push_constant_ranges,
        &push_constant_range};

    res = vkCreatePipelineLayout(m_device->vulkan_device(),
                                 &pipelineLayoutCreateInfo, 0,
                                 &m_pipeline_layout);
    if (res != VK_SUCCESS) {
        cvk_error("Could not create pipeline layout.");
        return CL_INVALID_VALUE;
    }

    // Determine number and types of bindings
    std::vector<VkDescriptorPoolSize> poolSizes(bindingTypes.size());

    int bidx = 0;
    for (auto& bt : bindingTypes) {
        poolSizes[bidx].type = bt.first;
        poolSizes[bidx].descriptorCount = bt.second * MAX_INSTANCES;
        bidx++;
    }

    // Create descriptor pool
    if (poolSizes.size() > 0) {
        VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {
            VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
            nullptr,
            VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // flags
            MAX_INSTANCES * spir_binary::MAX_DESCRIPTOR_SETS,  // maxSets
            static_cast<uint32_t>(poolSizes.size()),           // poolSizeCount
            poolSizes.data(),                                  // pPoolSizes
        };

        res = vkCreateDescriptorPool(m_device->vulkan_device(),
                                     &descriptorPoolCreateInfo, 0,
                                     &m_descriptor_pool);

        if (res != VK_SUCCESS) {
            cvk_error("Could not create descriptor pool.");
            return CL_INVALID_VALUE;
        }
    }

    return CL_SUCCESS;
}

VkPipeline
cvk_entry_point::create_pipeline(const cvk_spec_constant_map& spec_constants) {
    std::lock_guard<std::mutex> lock(m_pipeline_cache_lock);

    // Check for a cached pipeline using the same specialization constants
    if (m_pipelines.count(spec_constants)) {
        VkPipeline pipeline = m_pipelines.at(spec_constants);
        cvk_info("reusing pipeline %p for kernel %s", pipeline, m_name.c_str());
        return pipeline;
    }

    std::vector<VkSpecializationMapEntry> mapEntries;
    std::vector<uint32_t> specConstantData;
    uint32_t constantDataOffset = 0;
    for (auto& spec_const : spec_constants) {
        VkSpecializationMapEntry entry = {spec_const.first, constantDataOffset,
                                          sizeof(uint32_t)};
        mapEntries.push_back(entry);
        specConstantData.push_back(spec_const.second);
        constantDataOffset += sizeof(uint32_t);
    }

    VkSpecializationInfo specializationInfo = {
        static_cast<uint32_t>(mapEntries.size()),
        mapEntries.data(),
        specConstantData.size() * sizeof(uint32_t),
        specConstantData.data(),
    };

    void* pipelineShaderStageCreateInfoPNext = nullptr;
    VkPipelineShaderStageRequiredSubgroupSizeCreateInfo
        reqdSubgroupSizeCreateInfo;
    if (m_device->supports_subgroup_size_selection()) {
        auto reqdSubgroupSize = m_program->required_sub_group_size(m_name);
        if (reqdSubgroupSize > m_device->max_sub_group_size() ||
            reqdSubgroupSize < m_device->min_sub_group_size()) {
            if (reqdSubgroupSize != 0) {
                cvk_error_fn("required subgroup size '%u' for '%s' is out of "
                             "the supported range [%u, %u]",
                             reqdSubgroupSize, m_name.c_str(),
                             m_device->min_sub_group_size(),
                             m_device->max_sub_group_size());
                return VK_NULL_HANDLE;
            }
            reqdSubgroupSize = m_device->sub_group_size();
        }
        reqdSubgroupSizeCreateInfo.sType =
            VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO;
        reqdSubgroupSizeCreateInfo.pNext = nullptr;
        reqdSubgroupSizeCreateInfo.requiredSubgroupSize = reqdSubgroupSize;
        pipelineShaderStageCreateInfoPNext = &reqdSubgroupSizeCreateInfo;
    }

    const VkComputePipelineCreateInfo createInfo = {
        VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // sType
        nullptr,                                        // pNext
        0,                                              // flags
        {
            VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
            pipelineShaderStageCreateInfoPNext,                  // pNext
            0,                                                   // flags
            VK_SHADER_STAGE_COMPUTE_BIT,                         // stage
            m_program->shader_module(),                          // module
            m_name.c_str(),
            &specializationInfo // pSpecializationInfo
        },                      // stage
        m_pipeline_layout,      // layout
        VK_NULL_HANDLE,         // basePipelineHandle
        0                       // basePipelineIndex
    };

    VkPipeline pipeline;
    VkResult res = vkCreateComputePipelines(m_device->vulkan_device(),
                                            m_program->pipeline_cache(), 1,
                                            &createInfo, nullptr, &pipeline);

    if (res != VK_SUCCESS) {
        cvk_error_fn("Could not create compute pipeline for kernel %s: %s",
                     vulkan_error_string(res), m_name.c_str());
        return VK_NULL_HANDLE;
    }

    // Add to pipeline cache
    m_pipelines[spec_constants] = pipeline;

    cvk_info("created pipeline %p for kernel %s", pipeline, m_name.c_str());

    return pipeline;
}

bool cvk_entry_point::allocate_descriptor_sets(VkDescriptorSet* ds) {
    TRACE_FUNCTION();

    if (m_descriptor_set_layouts.size() == 0) {
        return true;
    }

    std::lock_guard<std::mutex> lock(m_descriptor_pool_lock);

#if CLVK_UNIT_TESTING_ENABLED
    if (config.force_descriptor_set_allocation_failure() &&
        m_nb_descriptor_set_allocated + m_descriptor_set_layouts.size() >
            config.max_entry_points_instances()) {
        return false;
    }
#endif

    VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {
        VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, nullptr,
        m_descriptor_pool,
        static_cast<uint32_t>(
            m_descriptor_set_layouts.size()), // descriptorSetCount
        m_descriptor_set_layouts.data()};

    VkResult res = vkAllocateDescriptorSets(m_device->vulkan_device(),
                                            &descriptorSetAllocateInfo, ds);

    if (res != VK_SUCCESS) {
        if (config.enqueue_command_retry_sleep_us == UINT32_MAX) {
            cvk_error_fn("could not allocate descriptor sets: %s",
                         vulkan_error_string(res));
        } else if (m_first_allocation_failure) {
            cvk_warn_fn(
                "could not allocate descriptor sets: %s, retry in %u us",
                vulkan_error_string(res),
                config.enqueue_command_retry_sleep_us());
        } else {
            cvk_info_fn("could not allocate descriptor sets: %s",
                        vulkan_error_string(res));
        }
        m_first_allocation_failure = false;
        return false;
    }

    m_nb_descriptor_set_allocated += m_descriptor_set_layouts.size();
    TRACE_CNT(descriptor_set_allocated_counter, m_nb_descriptor_set_allocated);

    return true;
}

std::unique_ptr<cvk_buffer> cvk_entry_point::allocate_pod_buffer() {
    cl_int err;
    auto buffer =
        cvk_buffer::create(m_context, 0, m_pod_buffer_size, nullptr, &err);
    if (err != CL_SUCCESS) {
        return nullptr;
    }

    return buffer;
}

bool cvk_entry_point::uses_printf() const {
    return m_program->kernel_flags(m_name) &
           NonSemanticClspvReflectionMayUsePrintf;
}
