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