Hi!

On 2026-06-23T16:28:13+0800, Chung-Lin Tang <[email protected]> wrote:
> --- a/libgomp/config/nvptx/allocator.c
> +++ b/libgomp/config/nvptx/allocator.c
> @@ -54,6 +54,9 @@ asm (".extern .shared .u8 __nvptx_lowlat_pool[];\n");
>  static void *
>  nvptx_memspace_alloc (omp_memspace_handle_t memspace, size_t size)
>  {
> +#if __PTX_ISA_VERSION_MAJOR__ > 4                                    \
> +    || (__PTX_ISA_VERSION_MAJOR__ == 4 && __PTX_ISA_VERSION_MINOR >= 1)
> +  /* Low-latency memory is not available before PTX 4.1.  */
>    if (memspace == omp_low_lat_mem_space)
>      {
>        char *shared_pool;
|        asm ("cvta.shared.u64\t%0, __nvptx_lowlat_pool;" : "=r" (shared_pool));
|  
|        return __nvptx_lowlat_calloc (shared_pool, size);
|      }
|    else if (memspace > GOMP_OMP_PREDEF_MEMSPACE_MAX)
>      /* No non-standard memspaces are implemented for device-side nvptx.  */
>      return NULL;
>    else
> +#endif
>      return malloc (size);
>  }

For PTX < 4.1, this disables the 'return NULL;' for
'memspace > GOMP_OMP_PREDEF_MEMSPACE_MAX'.  Shouldn't that still be done
in this case, too?  (I'm not familiar with the exact semantics of OpenMP
memory allocators and their libgomp implementation.)

>  static void *
>  nvptx_memspace_calloc (omp_memspace_handle_t memspace, size_t size)
>  {
> +#if __PTX_ISA_VERSION_MAJOR__ > 4                                    \
> +    || (__PTX_ISA_VERSION_MAJOR__ == 4 && __PTX_ISA_VERSION_MINOR >= 1)
> +  /* Low-latency memory is not available before PTX 4.1.  */
>    if (memspace == omp_low_lat_mem_space)
>      {
>        char *shared_pool;
> @@ -82,12 +89,16 @@ nvptx_memspace_calloc (omp_memspace_handle_t memspace, 
> size_t size)
>      /* No non-standard memspaces are implemented for device-side nvptx.  */
>      return NULL;
>    else
> +#endif
>      return calloc (1, size);
>  }

Likewise.

> @@ -103,6 +115,9 @@ static void *
>  nvptx_memspace_realloc (omp_memspace_handle_t memspace, void *addr,
>                       size_t oldsize, size_t size)
>  {
> +#if __PTX_ISA_VERSION_MAJOR__ > 4 \
> +    || (__PTX_ISA_VERSION_MAJOR__ == 4 && __PTX_ISA_VERSION_MINOR >= 1)
> +  /* Low-latency memory is not available before PTX 4.1.  */
>    if (memspace == omp_low_lat_mem_space)
>      {
>        char *shared_pool;
> @@ -110,13 +125,21 @@ nvptx_memspace_realloc (omp_memspace_handle_t memspace, 
> void *addr,
>  
>        return __nvptx_lowlat_realloc (shared_pool, addr, oldsize, size);
>      }
> -  else if (memspace > GOMP_OMP_PREDEF_MEMSPACE_MAX)
> -    /* No non-standard memspaces are implemented for device-side nvptx.  */
> -    return NULL;
>    else
> -    return realloc (addr, size);
> +#endif
> +    {
> +      if (memspace > GOMP_OMP_PREDEF_MEMSPACE_MAX)
> +     /* No non-standard memspaces are implemented for device-side nvptx.  */
> +     return NULL;
> +      else
> +     return realloc (addr, size);
> +    }
>  }

Here, on the other hand, you appear to handle this case (assuming that
I'm understanding this correctly)?


Relatedly:

> +/* The MEMSPACE_VALIDATE implementation should be kept in sync with
> +   the GOMP_OFFLOAD_memspace_validate plugin hook function in
> +   plugin/plugin-nvptx.c.  */
> +

But this:

>  static inline int
>  nvptx_memspace_validate (omp_memspace_handle_t memspace, unsigned access)
>  {
|  #if __PTX_ISA_VERSION_MAJOR__ > 4 \
|      || (__PTX_ISA_VERSION_MAJOR__ == 4 && __PTX_ISA_VERSION_MINOR >= 1)
|    /* Disallow use of low-latency memory when it must be accessible by
|       all threads.  */
|    if (memspace == omp_low_lat_mem_space
|        && access == omp_atv_all)
|      return false;
|  #else
|    /* Low-latency memory is not available before PTX 4.1.  */
|    if (memspace == omp_low_lat_mem_space)
|      return false;
|  #endif
|  
|    /* Otherwise, standard memspaces are accepted, even when we don't have
|       anything special to do with them, and non-standard memspaces are assumed
|       to need explicit support.  */
|    return (memspace <= GOMP_OMP_PREDEF_MEMSPACE_MAX);
|  }

... is now *not* in sync with:

> --- a/libgomp/plugin/plugin-nvptx.c
> +++ b/libgomp/plugin/plugin-nvptx.c

> +/* This plugin hook function should be kept in sync with 
> nvptx_memspace_validate
> +   in config/nvptx/allocator.c.  */
> +
> +int
> +GOMP_OFFLOAD_memspace_validate (omp_memspace_handle_t memspace, unsigned 
> access)
> +{
> +  /* Disallow use of low-latency memory when it must be accessible by
> +     all threads.  */
> +  if (memspace == omp_low_lat_mem_space
> +      && access == omp_atv_all)
> +    return false;
> +
> +  /* Otherwise, standard memspaces are accepted, even when we don't have
> +     anything special to do with them, and non-standard memspaces are assumed
> +     to need explicit support.  */
> +  return (memspace <= GOMP_OMP_PREDEF_MEMSPACE_MAX);
> +}

This one here doesn't consider PTX < 4.1 specially?

Now, the problem is, in host code, we can't know what kind of device code
we've got (what PTX version it's been compiled against)...

Clearly, PTX < 4.1 is not a common configuration anymore.  Even if we're
not going to fix this up properly, I'd still like to understand what goes
wrong (in terms of OpenMP user code) if
'libgomp/plugin/plugin-nvptx.c:GOMP_OFFLOAD_memspace_validate' vs.
'libgomp/config/nvptx/allocator.c:nvptx_memspace_validate' for PTX < 4.1,
'memspace == omp_low_lat_mem_space' provide conflicting answers?


Grüße
 Thomas

Reply via email to