diff --git a/libcudacxx/codegen/add_ptx_instruction.py b/libcudacxx/codegen/add_ptx_instruction.py index 2fe4def4e3d..0fe3136aa8f 100755 --- a/libcudacxx/codegen/add_ptx_instruction.py +++ b/libcudacxx/codegen/add_ptx_instruction.py @@ -1,12 +1,25 @@ #!/usr/bin/env python3 + +##===----------------------------------------------------------------------===## +## +## Part of libcu++, the C++ Standard Library for your entire system, +## 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. +## +##===----------------------------------------------------------------------===## + import argparse -from pathlib import Path +import os + +import cccl_paths -docs = Path("docs/libcudacxx/ptx/instructions") -test = Path("libcudacxx/test/libcudacxx/cuda/ptx") -src = Path("libcudacxx/include/cuda/__ptx/instructions") -ptx_header = Path("libcudacxx/include/cuda/ptx") -instr_docs = Path("docs/libcudacxx/ptx/instructions.rst") +docs = os.path.join(cccl_paths.DOCS_LIBCUDACXX_DIR, "ptx", "instructions") +test = os.path.join(cccl_paths.LIBCUDACXX_TEST_DIR, "libcudacxx", "cuda", "ptx") +src = os.path.join(cccl_paths.LIBCUDACXX_INCLUDE_DIR, "cuda", "__ptx", "instructions") +ptx_header = os.path.join(cccl_paths.LIBCUDACXX_INCLUDE_DIR, "cuda", "ptx") +instr_docs = os.path.join(cccl_paths.DOCS_LIBCUDACXX_DIR, "ptx", "instructions.rst") def add_docs(ptx_instr, url): diff --git a/libcudacxx/codegen/cccl_paths.py b/libcudacxx/codegen/cccl_paths.py new file mode 100644 index 00000000000..453525232a1 --- /dev/null +++ b/libcudacxx/codegen/cccl_paths.py @@ -0,0 +1,21 @@ +##===----------------------------------------------------------------------===## +## +## Part of libcu++, the C++ Standard Library for your entire system, +## 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. +## +##===----------------------------------------------------------------------===## + +import os + +LIBCUDACXX_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +LIBCUDACXX_CMAKE_DIR = os.path.join(LIBCUDACXX_DIR, "cmake") +LIBCUDACXX_CODEGEN_DIR = os.path.join(LIBCUDACXX_DIR, "codegen") +LIBCUDACXX_INCLUDE_DIR = os.path.join(LIBCUDACXX_DIR, "include") +LIBCUDACXX_TEST_DIR = os.path.join(LIBCUDACXX_DIR, "test") + +DOCS_DIR = os.path.dirname(LIBCUDACXX_DIR) +DOCS_LIBCUDACXX_DIR = os.path.join(DOCS_DIR, "libcudacxx") diff --git a/libcudacxx/codegen/generate_prologue_epilogue.py b/libcudacxx/codegen/generate_prologue_epilogue.py new file mode 100755 index 00000000000..6478ed67700 --- /dev/null +++ b/libcudacxx/codegen/generate_prologue_epilogue.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python3 + +##===----------------------------------------------------------------------===## +## +## Part of libcu++, the C++ Standard Library for your entire system, +## 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. +## +##===----------------------------------------------------------------------===## + +import datetime +import os + +import cccl_paths + +PROLOGUE_FILE = os.path.join( + cccl_paths.LIBCUDACXX_INCLUDE_DIR, "cuda", "std", "__cccl", "prologue.h" +) +EPILOGUE_FILE = os.path.join( + cccl_paths.LIBCUDACXX_INCLUDE_DIR, "cuda", "std", "__cccl", "epilogue.h" +) + +HEADER = f"""\ +//===----------------------------------------------------------------------===// +// +// Part of libcu++, the C++ Standard Library for your entire system, +// 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) {datetime.datetime.now().year} NVIDIA CORPORATION & AFFILIATES. +// +//===----------------------------------------------------------------------===// + +// !!! DO NOT EDIT THIS FILE !!! This file is generated by utils/generate_prologue_epilogue.py. + +// NO include guards here (this file is included multiple times)""" + +FOOTER = """\ +// NO include guards here (this file is included multiple times) +""" + +PUSH_POP_MACROS = { + "__declspec modifiers": [ + "align", + "allocate", + "allocator", + "appdomain", + "code_seg", + "deprecated", + "dllimport", + "dllexport", + "empty_bases", + "hybrid_patchable", + "jitintrinsic", + "naked", + "noalias", + "noinline", + "noreturn", + "nothrow", + "novtable", + "no_sanitize_address", + "process", + "property", + "restrict", + "safebuffers", + "selectany", + "spectre", + "thread", + "uuid", + ], + "[[msvc::attribute]] attributes": [ + "msvc", + "flatten", + "forceinline", + "forceinline_calls", + "intrinsic", + "noinline", + "noinline_calls", + "no_tls_guard", + ], + "Windows nasty macros": ["min", "max", "interface"], + "sal.h on Windows": ["__valid", "__callback"], + "other macros": ["clang"], + "sys/sysmacros.h on linux": ["major", "minor", "makedev"], +} + + +def write_section(file, section): + file.write(section) + file.write("\n\n") + + +def make_prologue(file): + # Write common header. + write_section(file, HEADER) + + # Add prologue/epilogue include logic check. + write_section( + file, + """\ +#if defined(_CCCL_PROLOGUE_INCLUDED) +# error \\ + "cccl internal error: must be included before next is reincluded" +#endif +#define _CCCL_PROLOGUE_INCLUDED() 1""", + ) + + # Add necessary includes. + write_section( + file, + """\ +#include +#include +#include """, + ) + + # Add push macros. + for group_name, macros in PUSH_POP_MACROS.items(): + write_section(file, f"// {group_name}") + for macro in macros: + write_section( + file, + f'''\ +#if defined({macro}) +# pragma push_macro("{macro}") +# undef {macro} +# define _CCCL_POP_MACRO_{macro} +#endif // defined({macro})''', + ) + + # Add warnings suppressions. + write_section( + file, + '''\ +_CCCL_DIAG_PUSH +_CCCL_NV_DIAG_PUSH() + +// disable some msvc warnings +// https://github.com/microsoft/STL/blob/master/stl/inc/yvals_core.h#L353 +// warning C4100: 'quack': unreferenced formal parameter +// warning C4127: conditional expression is constant +// warning C4180: qualifier applied to function type has no meaning; ignored +// warning C4197: 'purr': top-level volatile in cast is ignored +// warning C4324: 'roar': structure was padded due to alignment specifier +// warning C4455: literal suffix identifiers that do not start with an underscore are reserved +// warning C4503: 'hum': decorated name length exceeded, name was truncated +// warning C4522: 'woof' : multiple assignment operators specified +// warning C4668: 'meow' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' +// warning C4800: 'boo': forcing value to bool 'true' or 'false' (performance warning) +// warning C4996: 'meow': was declared deprecated +_CCCL_DIAG_SUPPRESS_MSVC(4100 4127 4180 4197 4296 4324 4455 4503 4522 4668 4800 4996) + +// disable warnings about using C++23 features in C++20 (needed for if consteval) +#if _CCCL_HAS_IF_CONSTEVAL_IN_CXX20() +# if _CCCL_COMPILER(GCC, >=, 12) +_CCCL_DIAG_SUPPRESS_GCC("-Wc++23-extensions") +# endif // _CCCL_COMPILER(GCC, >=, 12) +# if _CCCL_COMPILER(CLANG, >=, 17) +_CCCL_DIAG_SUPPRESS_CLANG("-Wc++23-extensions") +# else // ^^^ _CCCL_COMPILER(CLANG, >=, 17) ^^^ / vvv _CCCL_COMPILER(CLANG, <, 17) vvv +_CCCL_DIAG_SUPPRESS_CLANG("-Wc++2b-extensions") +# endif // ^^^ _CCCL_COMPILER(CLANG, <, 17) ^^^ +_CCCL_DIAG_SUPPRESS_NVHPC(if_consteval_nonstandard) + +_CCCL_DIAG_SUPPRESS_NVCC(3215) // "if consteval" and "if not consteval" are not standard in this mode +#endif // _CCCL_HAS_IF_CONSTEVAL_IN_CXX20() + +_CCCL_DIAG_SUPPRESS_NVHPC(is_constant_evaluated_in_nonconstexpr_context) + +_CCCL_DIAG_SUPPRESS_NVCC(3206) // "if consteval" and "if not consteval" are meaningless in a non-constexpr function +_CCCL_DIAG_SUPPRESS_NVCC(3060) // call to __builtin_is_constant_evaluated appearing in a non-constexpr function always + // produces "false"''', + ) + + # Write the common footer. + file.write(FOOTER) + + +def make_epilogue(file): + # Write common header. + write_section(file, HEADER) + + # Write includes. + write_section( + file, + """\ +#include +#include """, + ) + + # Add prologue/epilogue include logic check. + write_section( + file, + """\ +#if !defined(_CCCL_PROLOGUE_INCLUDED) +# error "cccl internal error: must be included before " +#endif +#undef _CCCL_PROLOGUE_INCLUDED""", + ) + + # Pop warning suppressions. + write_section( + file, + """\ +_CCCL_NV_DIAG_POP() +_CCCL_DIAG_POP""", + ) + + # Add pop macros. + for group_name, macros in PUSH_POP_MACROS.items(): + write_section(file, f"// {group_name}") + for macro in macros: + write_section( + file, + f'''\ +#if defined({macro}) +# error \\ + "cccl internal error: macro `{macro}` was redefined between and " +#elif defined(_CCCL_POP_MACRO_{macro}) +# pragma pop_macro("{macro}") +# undef _CCCL_POP_MACRO_{macro} +#endif''', + ) + + # Write the common footer. + file.write(FOOTER) + + +if __name__ == "__main__": + with open(PROLOGUE_FILE, "w") as file: + make_prologue(file) + + with open(EPILOGUE_FILE, "w") as file: + make_epilogue(file) diff --git a/libcudacxx/include/cuda/std/__cccl/epilogue.h b/libcudacxx/include/cuda/std/__cccl/epilogue.h index f657bda8ac1..b5b790bad99 100644 --- a/libcudacxx/include/cuda/std/__cccl/epilogue.h +++ b/libcudacxx/include/cuda/std/__cccl/epilogue.h @@ -4,10 +4,12 @@ // 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. +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. // //===----------------------------------------------------------------------===// +// !!! DO NOT EDIT THIS FILE !!! This file is generated by utils/generate_prologue_epilogue.py. + // NO include guards here (this file is included multiple times) #include @@ -18,7 +20,6 @@ #endif #undef _CCCL_PROLOGUE_INCLUDED -// warnings pop _CCCL_NV_DIAG_POP() _CCCL_DIAG_POP @@ -352,4 +353,30 @@ _CCCL_DIAG_POP # undef _CCCL_POP_MACRO_clang #endif +// sys/sysmacros.h on linux + +#if defined(major) +# error \ + "cccl internal error: macro `major` was redefined between and " +#elif defined(_CCCL_POP_MACRO_major) +# pragma pop_macro("major") +# undef _CCCL_POP_MACRO_major +#endif + +#if defined(minor) +# error \ + "cccl internal error: macro `minor` was redefined between and " +#elif defined(_CCCL_POP_MACRO_minor) +# pragma pop_macro("minor") +# undef _CCCL_POP_MACRO_minor +#endif + +#if defined(makedev) +# error \ + "cccl internal error: macro `makedev` was redefined between and " +#elif defined(_CCCL_POP_MACRO_makedev) +# pragma pop_macro("makedev") +# undef _CCCL_POP_MACRO_makedev +#endif + // NO include guards here (this file is included multiple times) diff --git a/libcudacxx/include/cuda/std/__cccl/prologue.h b/libcudacxx/include/cuda/std/__cccl/prologue.h index dee9b9d37a4..8850045da39 100644 --- a/libcudacxx/include/cuda/std/__cccl/prologue.h +++ b/libcudacxx/include/cuda/std/__cccl/prologue.h @@ -4,10 +4,12 @@ // 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. +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. // //===----------------------------------------------------------------------===// +// !!! DO NOT EDIT THIS FILE !!! This file is generated by utils/generate_prologue_epilogue.py. + // NO include guards here (this file is included multiple times) #if defined(_CCCL_PROLOGUE_INCLUDED) @@ -270,6 +272,26 @@ # define _CCCL_POP_MACRO_clang #endif // defined(clang) +// sys/sysmacros.h on linux + +#if defined(major) +# pragma push_macro("major") +# undef major +# define _CCCL_POP_MACRO_major +#endif // defined(major) + +#if defined(minor) +# pragma push_macro("minor") +# undef minor +# define _CCCL_POP_MACRO_minor +#endif // defined(minor) + +#if defined(makedev) +# pragma push_macro("makedev") +# undef makedev +# define _CCCL_POP_MACRO_makedev +#endif // defined(makedev) + _CCCL_DIAG_PUSH _CCCL_NV_DIAG_PUSH()