Skip to content

[Code scan] Validate TensorFlow tabulation GPU sizes before launching kernels #5654

Description

@njzjz

This issue comes from a Codex global scan of deepmodeling/deepmd-kit at commit 73de44b1f94471b2e3bdb6b11f57b34d7bc791bb.

Problem

Several TensorFlow tabulation GPU paths validate last_layer_size <= 1024 only after launching the CUDA/ROCm kernel.

Examples in the grad-grad paths:

  • if (device == "GPU") {
    #if GOOGLE_CUDA || TENSORFLOW_USE_ROCM
    deepmd::tabulate_fusion_se_a_grad_grad_gpu(
    dz_dy, table, table_info, em_x, em, two_embed, dz_dy_dem_x, dz_dy_dem,
    dz_dy_dtwo, nloc, nnei, last_layer_size, is_sorted);
    #endif // GOOGLE_CUDA || TENSORFLOW_USE_ROCM
    OP_REQUIRES(context, (last_layer_size <= 1024),
    deepmd::tf_compat::InvalidArgument(
    "In the process of model compression, the size of the "
    "last layer of embedding net must be less than 1024!"));
  • if (device == "GPU") {
    #if GOOGLE_CUDA || TENSORFLOW_USE_ROCM
    deepmd::tabulate_fusion_se_a_grad_grad_gpu(
    dz_dy, table, table_info, em_x, em, two_embed, dz_dy_dem_x, dz_dy_dem,
    dz_dy_dtwo, nloc, nnei, last_layer_size, is_sorted);
    #endif // GOOGLE_CUDA || TENSORFLOW_USE_ROCM
    OP_REQUIRES(context, (last_layer_size <= 1024),
    deepmd::tf_compat::InvalidArgument(
    "In the process of model compression, the size of the "
    "last layer of embedding net must be less than 1024!"));
  • if (device == "GPU") {
    #if GOOGLE_CUDA || TENSORFLOW_USE_ROCM
    deepmd::tabulate_fusion_se_t_grad_grad_gpu(
    dz_dy, table, table_info, em_x, em, dz_dy_dem_x, dz_dy_dem, nloc,
    nnei_i, nnei_j, last_layer_size);
    #endif // GOOGLE_CUDA || TENSORFLOW_USE_ROCM
    OP_REQUIRES(context, (last_layer_size <= 1024),
    deepmd::tf_compat::InvalidArgument(
    "In the process of model compression, the size of the "
    "last layer of embedding net must be less than 1024!"));
  • if (device == "GPU") {
    #if GOOGLE_CUDA || TENSORFLOW_USE_ROCM
    deepmd::tabulate_fusion_se_r_grad_grad_gpu(
    dz_dy, table, table_info, em, dz_dy_dem, nloc, nnei, last_layer_size);
    #endif // GOOGLE_CUDA || TENSORFLOW_USE_ROCM
    OP_REQUIRES(context, (last_layer_size <= 1024),
    deepmd::tf_compat::InvalidArgument(
    "In the process of model compression, the size of the "
    "last layer of embedding net must be less than 1024!"));

The GPU wrappers launch kernels with last_layer_size as the block size or shared-memory dimension, for example:

  • void tabulate_fusion_se_a_gpu(FPTYPE* out,
    const FPTYPE* table,
    const FPTYPE* table_info,
    const FPTYPE* em_x,
    const FPTYPE* em,
    const FPTYPE* two_embed,
    const int nloc,
    const int nnei,
    const int last_layer_size,
    const bool is_sorted) {
    if (nloc <= 0) {
    return;
    }
    DPErrcheck(gpuGetLastError());
    DPErrcheck(gpuDeviceSynchronize());
    tabulate_fusion_se_a_fifth_order_polynomial<FPTYPE, MM, KK>
    #if GOOGLE_CUDA
    <<<nloc, last_layer_size>>>
    #elif TENSORFLOW_USE_ROCM
    <<<nloc, last_layer_size, sizeof(FPTYPE) * MM * last_layer_size>>>
    #else
    #error "should not touch here"
    #endif
    (out, table, em_x, em, two_embed, table_info[0], table_info[1],
    table_info[2], table_info[3], table_info[4], nnei, last_layer_size,
    is_sorted);
  • void tabulate_fusion_se_a_grad_grad_gpu(FPTYPE* dz_dy,
    const FPTYPE* table,
    const FPTYPE* table_info,
    const FPTYPE* em_x,
    const FPTYPE* em,
    const FPTYPE* two_embed,
    const FPTYPE* dz_dy_dem_x,
    const FPTYPE* dz_dy_dem,
    const FPTYPE* dz_dy_dtwo,
    const int nloc,
    const int nnei,
    const int last_layer_size,
    const bool is_sorted) {
    if (nloc <= 0) {
    return;
    }
    DPErrcheck(gpuGetLastError());
    DPErrcheck(gpuDeviceSynchronize());
    DPErrcheck(gpuMemset(dz_dy, 0, sizeof(FPTYPE) * nloc * 4 * last_layer_size));
    tabulate_fusion_se_a_grad_grad_fifth_order_polynomial<FPTYPE, MM, KK>
    <<<nloc, last_layer_size, sizeof(FPTYPE) * MM * last_layer_size>>>(
    dz_dy, table, em_x, em, two_embed, dz_dy_dem_x, dz_dy_dem, dz_dy_dtwo,
    table_info[0], table_info[1], table_info[2], table_info[3],
    table_info[4], nnei, last_layer_size, is_sorted);
    DPErrcheck(gpuGetLastError());

So oversized inputs can hit a CUDA runtime failure before TensorFlow returns the intended InvalidArgument.

Impact

Invalid compressed-model tabulation shapes can leave users with low-level GPU launch errors instead of a deterministic TensorFlow validation error. Forward tabulation paths also launch GPU kernels without the same prelaunch bound check.

Suggested fix

Validate last_layer_size > 0 && last_layer_size <= 1024 before every GPU tabulation wrapper call that uses it as a kernel launch dimension or shared-memory multiplier.

Add GPU tests that pass last_layer_size=1025 and assert a clean TensorFlow InvalidArgument without launching the kernel.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status
    In Progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions