Issue 183557
Summary [flang][OpenMP] Custom mapper causes crash when target region accesses mapped variable through pointer indirection
Labels flang
Assignees
Reporter jfuchs-kmt
    Consider the snippet below. There is a derived type `field_t` that holds an allocatable and an integer for demonstration purposes. Additionally, there is a module holding a custom mapper for `field_t`, which only maps the allocatable.

The program executes two target regions:
1. A field instance is created locally, it is entered into the device data environment and through a `target teams loop` we write some value to its allocatable member. Note that the field is already entered into the device data environment upon reaching the target region. This should be recognized and no mappings should occur. Everything behaves as expected.
2. A field is set and entered into the device data environment in another module. We get a pointer to it through `get_field`. If this pointer is referred to in a target region, the program exits with the error below.
```
omptarget message: explicit extension not allowed: host address specified is 0x000061297c05d210 (52 bytes), but device allocation maps to host at 0x000061297c05d210 (48 bytes)
omptarget error: Call to getTargetPointer returned null pointer (device failure or illegal mapping).
omptarget error: Call to targetDataBegin via targetDataMapper for custom mapper failed
omptarget error: Call to targetDataBegin failed, abort target.
omptarget error: Failed to process data before launching the kernel.
omptarget error: Consult https://openmp.llvm.org/design/Runtimes.html for debugging options.
omptarget error: Source location information not present. Compile with -g or -gline-tables-only.
omptarget fatal error 1: failure of target construct while offloading is mandatory
Aborted (core dumped)
make: *** [Makefile:44: run] Error 134
```
It is unclear to me why the two versions behave differently (the `localfield` one does not crash, the one with pointer indirection crashes). I thought that the underlying runtime could see behind the pointer indirection of the second example, yet we still crash.
One can prevent the crash by appending `t%val` to the custom mapper such that the full type is mapped again. But that is not a solution since we try to avoid mapping member with the mapper.
Please correct me if I am misunderstanding the expected behavior, I am happy for any guidance.

flang version: `flang version 23.0.0git ([email protected]:llvm/llvm-project.git dd83ead9a51ff39fbde7e12fbf70a49a8353dbd2)`
Compile with: `flang -O2 -fopenmp -fopenmp-targets=nvptx64 -fopenmp-version=52 main.F90`

```fortran
MODULE realfield_mod
    IMPLICIT NONE
    PRIVATE

    TYPE field_t
 REAL, ALLOCATABLE :: arr(:)
        INTEGER :: val
    CONTAINS
 PROCEDURE, PUBLIC :: init
        PROCEDURE, PUBLIC :: finish
    END TYPE field_t

    PUBLIC :: field_t
CONTAINS
    SUBROUTINE init(this)
 CLASS(field_t), INTENT(INOUT) :: this
        
        this%val = 1
 ALLOCATE(this%arr(1024), source=1.0)
    END SUBROUTINE init

 SUBROUTINE finish(this)
        CLASS(field_t), INTENT(INOUT) :: this

 DEALLOCATE(this%arr)
    END SUBROUTINE
END MODULE realfield_mod

MODULE mapper_mod
    USE realfield_mod, ONLY: field_t
 PRIVATE :: field_t

    ! Use mapper_mod expose the custom mapper while keeping 
    ! realfield_mod private
    !$omp declare mapper(arr: field_t :: t) map(t%arr)
END MODULE mapper_mod

MODULE fields_mod
    USE mapper_mod
    USE realfield_mod
    IMPLICIT NONE
    PRIVATE

 TYPE(field_t), TARGET :: field

    PUBLIC :: finish_fields, set_field, get_field
CONTAINS
    SUBROUTINE finish_fields()
        INTEGER :: i
 !$omp target exit data map(mapper(arr), release: field)
        CALL field%finish()
    END SUBROUTINE finish_fields

    SUBROUTINE set_field()
        CALL field%init()
        !$omp target enter data map(mapper(arr), to: field)
    END SUBROUTINE set_field

    SUBROUTINE get_field(fieldptr)
        TYPE(field_t), POINTER, INTENT(INOUT) :: fieldptr
        fieldptr => field
    END SUBROUTINE
END MODULE fields_mod

PROGRAM reproducer
    USE fields_mod
    USE mapper_mod
 USE realfield_mod
    IMPLICIT NONE

    TYPE(field_t), POINTER :: fieldptr
    TYPE(field_t) :: localfield
    INTEGER :: i

    CALL localfield%init()
    !$omp target enter data map(mapper(arr), to: localfield)
    !$omp target teams loop
    DO i = 1, 1024 
 localfield%arr(i) = 42.0
    END DO
    !$omp end target teams loop
 !$omp target exit data map(mapper(arr), release: localfield)
    CALL localfield%finish()
    PRINT*, "localfield done"

    CALL set_field()
    CALL get_field(fieldptr)
    ! CRASHES HERE
    !$omp target teams loop 
    DO i = 1, 1024 
        fieldptr%arr(i) = 42.0
 END DO
    !$omp end target teams loop
    CALL finish_fields()
END PROGRAM reproducer
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to