//===----------------------------------------------------------------------===// // // Part of CUDA Experimental in CUDA C++ Core Libraries, // under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. // //===----------------------------------------------------------------------===// #pragma once #include #include #include #include "../util/errors.h" #include "../util/types.h" extern const char* jit_template_header_contents; template struct parameter_mapping; template struct template_id {}; // tagged_arg is needed to pass storage type information to the parameter // mapping. This is needed because different args may have different storage // types. template struct tagged_arg { using storage_type = StorageT; using value_type = T; T value; }; template struct is_tagged_arg : cuda::std::false_type {}; template struct is_tagged_arg> : cuda::std::true_type {}; template struct arg_traits { using storage_type = storage_t; using value_type = T; static constexpr const T& unwrap(const T& value) { return value; } static constexpr auto wrap(const T& value) { return tagged_arg{value}; } }; template struct arg_traits> { using storage_type = StorageT; using value_type = T; static constexpr const T& unwrap(const tagged_arg& value) { return value.value; } static constexpr const auto& wrap(const tagged_arg& value) { return value; } }; template struct mapping_arg_type { using type = T; }; template struct mapping_arg_type> { using type = T; }; struct specialization { std::string type_name; std::string aux_code = ""; }; template ::type>::archetype...>> specialization get_specialization(template_id id, Args... args) { #ifdef __CUDA_ARCH__ return specialization{}; #else if constexpr (requires { Traits::template special(args...); }) { if (auto result = Traits::template special(args...)) { return *result; } } std::string tag_name; check(cccl_type_name_from_nvrtc(&tag_name)); auto map = [&](auto arg) { using arg_t = cuda::std::decay_t; using map_t = typename mapping_arg_type::type; return parameter_mapping::map(id, arg); }; auto aux = [&](auto arg) { using arg_t = cuda::std::decay_t; using map_t = typename mapping_arg_type::type; return parameter_mapping::aux(id, arg); }; return {std::format("{}<{}{}>", Traits::name, tag_name, ((", " + map(args)) + ...)), std::format("struct {};", tag_name) + (aux(args) + ...)}; #endif }