Files
project_6_89d52222/cccl_upstream/c/parallel/src/util/nvjitlink.h
EngineX CI 56fd68e7dd [INFRA] Import NVIDIA/CCCL upstream as optimization reference library
CCCL (CUDA C++ Core Libraries) provides:
- CUB: device/block/warp-level GPU primitives (reduce, scan, sort, topk)
- Thrust: high-level parallel algorithms (transform_reduce, sort, scan)
- libcudacxx: CUDA C++ standard library (atomics, barriers, memory)
- cudax: experimental features (memory resources, allocators)
- Tuning policies: per-SM hardware-specific algorithm parameters

Competition optimization vectors mapped to CCCL:
- Output TPS (83% weight): warp_reduce, block_reduce, device_topk
- Input TPS (14% weight): device_scan, block_load, prefetch
- Cache TPS (3% weight): prefix caching strategy patterns
- Memory (0.9 util): pooled/cached/buddy allocators

Source: https://github.com/NVIDIA/cccl (shallow clone, HEAD only)
License: Apache-2.0
2026-07-30 09:35:51 +00:00

87 lines
2.2 KiB
C++

//===----------------------------------------------------------------------===//
//
// 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) 2026 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
#pragma once
#include <cstdio>
#include <format>
#include <memory>
#include <utility>
#include <nvrtc/nvjitlink_helper.h>
#include <util/errors.h>
// Links LTO-IR blobs via nvJitLink → returns SASS cubin (PTX fallback if SASS unavailable).
// Caller owns the returned buffer.
[[nodiscard]] inline std::pair<std::unique_ptr<char[]>, size_t>
nvjitlink_link(const void** blobs, const size_t* sizes, size_t num, int cc_major, int cc_minor)
{
const std::string arch = std::format("-arch=sm_{}{}", cc_major, cc_minor);
const char* lopts[] = {"-lto", arch.c_str()};
nvJitLinkHandle h{};
check(nvJitLinkCreate(&h, 2, lopts));
auto cleanup = [&]() {
if (h)
{
nvJitLinkDestroy(&h);
h = nullptr;
}
};
try
{
for (size_t i = 0; i < num; ++i)
{
if (blobs[i] && sizes[i] > 0)
{
check(nvJitLinkAddData(h, NVJITLINK_INPUT_ANY, blobs[i], sizes[i], "serialization_input"));
}
}
auto rc = nvJitLinkComplete(h);
size_t log_size = 0;
check(nvJitLinkGetErrorLogSize(h, &log_size));
if (log_size > 1)
{
auto log = std::make_unique<char[]>(log_size);
check(nvJitLinkGetErrorLog(h, log.get()));
fprintf(stderr, "%s\n", log.get());
}
check(rc);
size_t cubin_size = 0;
bool use_ptx = (nvJitLinkGetLinkedCubinSize(h, &cubin_size) != NVJITLINK_SUCCESS);
if (use_ptx)
{
check(nvJitLinkGetLinkedPtxSize(h, &cubin_size));
}
auto cubin = std::make_unique<char[]>(cubin_size);
if (use_ptx)
{
check(nvJitLinkGetLinkedPtx(h, cubin.get()));
}
else
{
check(nvJitLinkGetLinkedCubin(h, cubin.get()));
}
cleanup();
return {std::move(cubin), cubin_size};
}
catch (...)
{
cleanup();
throw;
}
}