Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

start of array is mapped regardless of explicit map clause #54899

Closed
jdenny-ornl opened this issue Apr 13, 2022 · 18 comments
Closed

start of array is mapped regardless of explicit map clause #54899

jdenny-ornl opened this issue Apr 13, 2022 · 18 comments
Labels

Comments

@jdenny-ornl
Copy link
Collaborator

I'm seeing unexpected behavior starting at @ye-luo's recent c1a6fe1 (D123093): the start of an array is mapped regardless of its explicit map clause. I can still reproduce at today's 82e5976. I've tested while offloading to nvptx64.

For example, the following prints 1, but it used to print 0 before c1a6fe1:

#include <omp.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
  int arr[1000];
  #pragma omp target data map(tofrom:arr[998:1])
  {
    printf("%d\n", omp_target_is_present(arr, omp_get_default_device()));
  }
  return 0;
}
@llvmbot
Copy link
Member

llvmbot commented Apr 13, 2022

@llvm/issue-subscribers-openmp

@ye-luo
Copy link
Contributor

ye-luo commented Apr 13, 2022

Since spec 5.1

If the value of a given pointer is in the mapped address range of a currently mapped list item then 
that currently mapped list item is a matching mapped list item. Otherwise, if the value of the
pointer is in the extended address range of a currently mapped list item then that currently mapped
list item is a matching mapped list item.

In your case, the pointer lands in the extended address range. So it is considered found in the existing maps.
I'd like to see more opinions. Maybe this can be refined.

@jdenny-ornl
Copy link
Collaborator Author

Looking at OpenMP 5.2 sec. 18.8.3 "omp_target_is_present", "Effect":

The omp_target_is_present routine returns true if device_num refers to the host device or
if ptr refers to storage that has corresponding storage in the device data environment of device
device_num. Otherwise, the routine returns false.

In my example, arr does not refer to storage that has corresponding storage in the device data environment, right?

@jdenny-ornl
Copy link
Collaborator Author

Keep in mind that my example uses a target data construct. The first sentence of the section you're quoting says it talks about target constructs:

This section describes how a pointer that is predetermined firstprivate for a target construct may
be assigned an initial value that is the address of an object that exists in a device data environment
and corresponds to a matching mapped list item.

That doesn't apply in my example, right?

@ye-luo
Copy link
Contributor

ye-luo commented Apr 13, 2022

I think you are right. I need to find a way to distinguish both cases.

@RaviNarayanaswamy
Copy link

Even though target data maps 1 element of arr at offset 998., the present check on arr should return true.

@jdenny-ornl
Copy link
Collaborator Author

Even though target data maps 1 element of arr at offset 998., the present check on arr should return true.

Are you arguing that arr does "refer to storage that has corresponding storage in the device data environment"? Or does the omp_target_is_present description need to change?

@RaviNarayanaswamy
Copy link

What I am saying is that arr has a corresponding storage on the device. Not all memory of host is present on device and is an error accessing them. Can only access memory which is allocated on device

@ye-luo
Copy link
Contributor

ye-luo commented Apr 13, 2022

omp_target_is_present, returns true if

  1. pointer found in the mapped address range
  2. pointer found in the extended address range

If I understood correctly.
Jeol is saying 1), Ravi is saying 2)
I see pros and cons of either choices. Let me ask the language committee.

@jdenny-ornl
Copy link
Collaborator Author

Surely map(present,alloc:arr[0:1]) is still expected to produce a runtime error after map(alloc:arr[998:1]). I suppose I expected omp_target_is_present to use the same definition of "present".

Yes, please let us know what the language committee says.

Thanks for everyone's replies.

@ye-luo
Copy link
Contributor

ye-luo commented Apr 13, 2022

Surely map(present,alloc:arr[0:1]) is still expected to produce a runtime error after map(alloc:arr[998:1]). I suppose I expected omp_target_is_present to use the same definition of "present".

Yes, please let us know what the language committee says.

Thanks for everyone's replies.

Indeed, I did exactly the same test on the present clause. There is no problem because there is no ambiguity.
arr[begin:size] array notation carries 3 pieces of info. Base address, begin address and size(end address).
omp_target_is_present(arr) only sees the base address. It is not equivalent to map(present,alloc:arr[0:1]) which checks 4 bytes (int) instead of 1.

@jdenny-ornl
Copy link
Collaborator Author

I understand omp_target_is_present doesn't take a size, so I assumed it would check the presence of a single byte. That brings more questions to mind:

  • What should omp_get_mapped_ptr(arr, dev) return? I'm assuming NULL, but maybe it's like omp_target_is_present instead?
  • What should omp_target_is_accessible(arr, 1, dev) return? Surely false.
  • What should omp_target_is_accessible(arr, 0, dev) return?

I realize omp_get_mapped_ptr and omp_target_is_accessible are not implemented yet upstream. I had prototyped them in my work and was planning to contribute that, but now I'm suspicious I've implemented them incorrectly.

@RaviNarayanaswamy
Copy link

What should omp_get_mapped_ptr(arr, dev) return?
return the associated arr pointer on the device
What should omp_target_is_accessible(arr, 1, dev) return? Surely false.
Yes false
What should omp_target_is_accessible(arr, 0, dev) return?
true

@ye-luo
Copy link
Contributor

ye-luo commented Apr 14, 2022

  • omp_get_mapped_ptr(arr, dev) the pointer lookup should succeed. So return the associated arr pointer on the device.
  • omp_target_is_accessible tests whether host memory is accessible from a given device. It has nothing to do with mapping. It is unclear to me what is the intention and how to implement this. In CUDA/HIP, even if you have pinned host memory. the point may not be used for accessing host on the device and you need cudaHostGetDevicePointer to translate to a pointer accessible on the device. However, I don't know if the translated pointer is still accessible from host. The host pointer and the translated pointer point to the same memory but the address may or may not be different.

@jdenny-ornl
Copy link
Collaborator Author

What should omp_target_is_accessible(arr, 0, dev) return?
true

Where does the spec clarify the size=0 case?

omp_target_is_accessible tests whether host memory is accessible from a given device. It has nothing to do with mapping.

Ravi's answer above for omp_target_is_accessible(arr, 0, dev) suggests it does see mappings. I assume omp_target_is_accessible(&arr[998], 1, dev) would also return true.

Somewhere I heard that omp_target_is_accessible returns true for unified shared memory as well as mapped memory, and omp_target_is_present returns true only for mapped memory. Maybe that's wrong. I don't trust my own read of the spec here.

@RaviNarayanaswamy
Copy link

The way I look at it is that if you specify a size for omp_target_is_accessible then the runtime checks if that size is allocated on the device then return true, if the size is zero, then you then return true if there is corresponding pointer on the device.

@jdenny-ornl
Copy link
Collaborator Author

The way I look at it is that if you specify a size for omp_target_is_accessible then the runtime checks if that size is allocated on the device then return true, if the size is zero, then you then return true if there is corresponding pointer on the device.

That sounds reasonable to me, but I cannot figure out where the spec says these things.

jdenny-ornl added a commit to llvm-doe-org/llvm-project that referenced this issue Apr 16, 2022
This merge brings in the following commits from upstream:

* 307bbd3, 4e34f06, b316126: These commits fix some
  exclusive access and race issues in libomptarget.  Many conflicts
  with Clacc's implementation result:
    * They make significant changes to the `HostDataToTargetMap` data
      structure in `openmp/libomptarget/include/device.h` and thus
      update code within `device.cpp`, `omptarget.cpp`, etc.  Parts of
      Clacc's OMPT offload prototype appear here.  This merge resolves
      conflicts in favor of upstream and then reapplies Clacc's
      changes based on the new data structure.  This merge also
      updates Clacc's `lookupHostPtr` and `getAccessibleBuffer`
      implementation in `device.cpp` to use the new
      `HostDataToTargetMap` interface.
	* They rearrange `InitLibrary` in
      `openmp/libomptarget/src/omptarget.cpp`.  Clacc adds an OMPT
      offload callback here.  This merge resolves conflicts in favor
      of upstream and then reinserts the OMPT callback.
    * They replace `DeallocTgtPtrInfo` with `PostProcessingInfo` in
      `openmp/libomptarget/src/omptarget.cpp`.  Clacc adds
      `HstPtrName` field to `DeallocTgtPtrInfo` for OMPT support and
      thus to related `emplace_back` calls.  However, that's now
      available via `PostProcessingInfo`'s `TPR` field, so this merge
      drops Clacc's change here.
    * They rewrite `targetDataEnd` in
      `openmp/libomptarget/src/omptarget.cpp`.  Clacc instantiates an
      `OmptMapVarInfoRAII` before the `Device.deallocTgtPtr` call
      there.  This merge resolves conflicts in favor of upstream and
      adds back the `OmptMapVarInfoRAII` instantiation.
    * As a drive-by fix, this merge adds `TIMESCOPE` calls to Clacc's
      implementations for `omp_target_is_accessible`,
      `omp_get_mapped_ptr`, `omp_get_mapped_hostptr`, and
      `omp_get_accessible_buffer`.
* c1a6fe1: This commit changes the way mapped variables are
  looked up in libomptarget:
    * An effect is that, if `arr[N:M]` is currently mapped, then
      `omp_target_is_present` now returns true and
      `omp_get_mapped_ptr` now returns a non-null device pointer when
      passed a host pointer within `arr[0:N]`.
    * Whether this new behavior is correct is being discussed in
      <llvm#54899> and at
      <omp-lang@openmp.org>.  No consensus has yet been reached.
	* The behavior of Clacc's implementations of
      `omp_target_is_accessible` and `omp_get_accessible_buffer` (a
      Clacc extension) are also affected for the case of size=0.  This
      merge updates comments on those to explain the issue.
	* The above OpenMP behavior changes affect Clacc's implementation
      of `acc_is_present` and `acc_deviceptr`.  This merge updates
      comments on those (and related comments on `acc_hostptr`) and
      adjusts their implementations so that they are immune to the
      OpenMP behavior change, even if it is later reverted.  It also
      adjusts the implementation of `checkPresence` in `api.cpp` so it
      is immune as well, but this adjustment is currently NFC, as
      explained in the new comments there.
	* This merge updates references to the OpenACC and OpenMP specs in
      many related comments.
* 79f661e, 6bd8dc9, 2cedaee, and f82ec55: These
  commits define new AST `Stmt` nodes (for the OpenMP loop construct)
  and thus insert new enumerators into `CXCursorKind` immediately
  before `CXCursor_LastStmt`.  Clacc does the same.  This merges
  combines those, keeping Clacc's enumerators last.
* Various commits with which this merge resolves contextual conflicts.
@ye-luo
Copy link
Contributor

ye-luo commented Apr 16, 2022

Added a patch https://reviews.llvm.org/D123891

@ye-luo ye-luo closed this as completed in 8a880db Apr 22, 2022
mem-frob pushed a commit to draperlaboratory/hope-llvm-project that referenced this issue Oct 7, 2022
…ero length array.

Consider checking whether a pointer has been mapped can be achieved via omp_get_mapped_ptr.
omp_target_is_present is more needed to check whether the storage being pointed is mapped.
This restore the old behavior of omp_target_is_present before D123093
Fixes llvm/llvm-project#54899

Reviewed By: jdenny

Differential Revision: https://reviews.llvm.org/D123891
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants