Skip to content

helloTile: per-sample build fails on Ubuntu/Debian/Fedora — _FORTIFY_SOURCE rewrites printf to a non-tile-callable __printf_chk (v13.3) #437

Description

@yashashav-dk

Summary

Building the cpp/9_CUDA_Tile/helloTile sample on its own (the per-sample build the README documents — "you can also follow this process … from within any individual sample") fails from a clean v13.3 checkout on a default Ubuntu 24.04 system, and on any distro whose GCC package defaults -D_FORTIFY_SOURCE on at -O1+ (Debian, Fedora). helloTile.cu calls printf from a __tile_global__ kernel, which CUDA 13.3 intends to allow — but with FORTIFY active, printf is rewritten to __printf_chk, which is not tile-callable, so nvcc rejects the call.

The whole-tree build from the repo root works (the FORTIFY workaround in the parent 9_CUDA_Tile/CMakeLists.txt is inherited there), so this is specific to the documented per-sample build path.

Environment

Component Value
OS Ubuntu 24.04.4 LTS (also affects Debian / Fedora; vanilla-GCC distros like Arch are unaffected)
CUDA Toolkit 13.3.r13.3 (nvcc V13.3.33)
GCC 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04.1)
glibc 2.39
CMake 4.3.2 (also reproduces with 3.28.3)
cuda-samples v13.3 (b7c5481)
GPU RTX PRO 6000 Blackwell (sm_120)

Reproduction

Per-sample build (documented as supported), which fails:

git clone --depth 1 --branch v13.3 https://github.com/NVIDIA/cuda-samples
cd cuda-samples/cpp/9_CUDA_Tile/helloTile
mkdir build && cd build
cmake .. -DCMAKE_CUDA_ARCHITECTURES="120" -DCMAKE_BUILD_TYPE=Release
make

Actual

helloTile.cu(48): error: calling a __host__ __device__ function("printf")
                   from a __tile_global__ function("tileKernel") is not allowed
helloTile.cu(49): error: calling a __host__ __device__ function("printf")
                   from a __tile_global__ function("tileKernel") is not allowed
helloTile.cu(52): error: calling a __host__ __device__ function("printf")
                   from a __tile_global__ function("tileKernel") is not allowed
3 errors detected in the compilation of "helloTile.cu".

Expected

The per-sample build succeeds (as the whole-tree build does) and the binary prints the Hello, SIMT! / Hello, Tile! / Hello, Host! sequence.

For contrast, the whole-tree build from the repo root does build this sample correctly:

cd cuda-samples
cmake -S . -B build -DCMAKE_CUDA_ARCHITECTURES="120" -DCMAKE_BUILD_TYPE=Release
cmake --build build --target helloTile   # succeeds

Root cause

  1. CUDA 13.3 declares printf as tile-callable. crt/common_functions.h re-declares printf with the tile / tile_builtin attributes (via the __NV_TL__ / __NV_TL_BUILTIN__ macros), so calling it from a __tile_global__ kernel is intended to be legal.
  2. GCC enables FORTIFY by default at -O1+. On Ubuntu/Debian/Fedora the GCC package injects -D_FORTIFY_SOURCE for optimized builds. On this box:
    $ echo | gcc -O2 -dM -E - | grep FORTIFY
    #define _FORTIFY_SOURCE 3
    # still present with -nostdinc, confirming GCC injects it (not a glibc header)
    
    The samples Release build uses -O2, so FORTIFY is active.
  3. glibc then rewrites printf__printf_chk. Under __USE_FORTIFY_LEVEL > 0, <bits/stdio2.h> provides an inline overload and a #define printf(...) macro that forward to __printf_chk, which glibc declares with no CUDA/tile attributes. A __tile_global__ kernel may only call __device__/__tile__ functions, so the redirected call is rejected.

(The diagnostic mentions printf because that's the original declaration; the actual call target after FORTIFY rewriting is the non-tile __printf_chk.)

Why only the per-sample build is affected

cpp/9_CUDA_Tile/CMakeLists.txt (the parent) already contains the fix:

add_compile_options(
    $<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-U_FORTIFY_SOURCE>
    $<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-D_FORTIFY_SOURCE=0>
)

add_compile_options sets a directory property. It is inherited when helloTile is built through that parent (the whole-tree build from the repo root), but not when helloTile/ is configured as its own top-level project — which is exactly the documented per-sample path. So the single-sample build a user would naturally run is the one that misses the workaround.

Note: building from the category directory (cmake -S cpp/9_CUDA_Tile) is not an alternative either — that parent has no project() / cmake_minimum_required(), so it can't be configured as a standalone top-level build.

Suggested fix

Minimal (per-leaf): add the same workaround to cpp/9_CUDA_Tile/helloTile/CMakeLists.txt, after find_package(CUDAToolkit REQUIRED):

# GCC packages (Ubuntu/Debian/Fedora) default _FORTIFY_SOURCE on at -O1+, which
# rewrites printf -> __printf_chk; __printf_chk is not callable from tile kernels.
# Needed per-leaf because the parent dir's add_compile_options is not inherited
# when this sample is configured as its own top-level project (per-sample build).
add_compile_options(
    $<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-U_FORTIFY_SOURCE>
    $<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-D_FORTIFY_SOURCE=0>
)

A cleaner variant: move the workaround into a shared cmake/Modules/ helper and include() it from each 9_CUDA_Tile/* leaf, so it survives leaf-only configures and covers any future tile sample that prints.

Verified: with this change the per-sample build succeeds and runs correctly on Blackwell (sm_120):

Hello, SIMT!
[SIMT] *x == 0
[SIMT] *x = 100

Hello, Tile!
[Tile] *x == 100
[Tile] *x = 200

Hello, Host!
[Host] *x == 200

(-O0 and -Xcompiler=-U_FORTIFY_SOURCE -Xcompiler=-D_FORTIFY_SOURCE=0 on the command line also work as ad-hoc workarounds.)

Separate, unrelated note

While checking the configure roots, a distinct v13.3 issue surfaced: cmake -S cpp (configuring the C++ subtree directly, rather than from the repo root) fails because several 4_CUDA_Libraries/* leaves declare project(<name> LANGUAGES CXX) but then call target_compile_features(... cuda_std_17) (no known features for CUDA compiler ""). It doesn't affect the repo-root build (which enables CUDA globally) and is independent of the tile/printf issue above — happy to file it separately; mentioned only for completeness.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions