-
Notifications
You must be signed in to change notification settings - Fork 423
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Closes #22822. This PR seeks to improve the experience of using various GPU attributes in several cases. These changes are motivated by some of the difficulties I've observed @Iainmon to have had while working on his GPU-enabled machine learning code. ## Case 1: Writing CPU and GPU code using the GPU locale model The way to ensure that a loop is GPU-eligible in user code (and to fail compilation if the loop is not GPU eligible), is to use `@assertOnGpu`. However, one cannot do this when writing code that is expected to support both GPUs and CPUs. I've observed Iain's code to have something like the following: ```Chapel if onGpu { @assertOnGpu foreach ... { } } else { foreach ... { /* the same loop as above */ } } ``` This way, the code could be used on both the GPU and the CPU, and the compiler will ensure that the GPU version is eligible. However, this introduces a maintenance burden, and makes the code rather verbose. To work around this problem, I introduce a new GPU primitive + attribute: `@gpu.assertEligible`. This attribute has the same behavior as `@assertOnGpu` at compile-time, but it does not have a runtime effect. Thus, the code above can be flattened and continue to support both CPU and GPU runs: ```Chapel if onGpu { @gpu.assertEligible foreach ... { } } ``` In my opinion, we should phase out the use of `@assertOnGpu` in favor of `@gpu.assertEligible`. It's unclear to me that having a runtime assertion using this attribute is worth keeping it around two similar attributes. Personally, I think that the compile-time assertion can be handled by `@gpu.assertEligible,` and various utilities from `GpuDiagnostics` for tracking kernel launches etc. can be used to ensure that GPU execution occurs at runtime. This PR doesn't make this (potentially more controversial change). ## Case 2: Disabling GPU support and compiling with `CHPL_LOCALE_MODEL=flat` When I told Iain to run his performance experiments in the flat locale model (to get started with initial performance results via the CPU), he immediately ran into internal errors. This is an instance of #22822. My chosen solution to this problem is to make `@assertOnGpu` a compile-time error under `CHPL_LOCALE_MODEL=flat`. This is because of the semantics of `@assertOnGpu`: this attribute has a runtime check; without a GPU, the check is guaranteed to fail, and cause a "certain" failure. This error is now user-facing, and tells the user to switch to `@gpu.assertEligible` if all they want is a compile-time check. On the other hand, the `@gpu.assertEligible` attribute, which does not have any runtime semantics, does not cause a compilation error with the `flat` locale model. Instead, the attribute is simply ignored (we don't perform any GPU logic with the flat locale model, and it doesn't seem worth it to actually perform GPU transformations / analysis for the sole purpose of validating GPU eligibility). The same is true for `@gpu.blockSize`, and the non-user-facing "GPU primitive block" primitive which is used to group GPU primitives created via attributes. Thus, the following code compiles and runs just fine in the `flat` locale model: ```Chapel @gpu.assertEligible @gpu.blockSize(128) foreach i in 1..128 { /* ... */ } ``` Reviewed by @e-kayrakli -- thanks! ## Testing - [x] new `flat` tests for GPU primitives, including a new user-facing error. - [x] GPU tests, including new tests for `@gpu.assertEligible` - [x] paratest
- Loading branch information
Showing
39 changed files
with
332 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* | ||
* Copyright 2024 Hewlett Packard Enterprise Development LP | ||
* Other additional copyright holders may be indicated within. | ||
* | ||
* The entirety of this work is licensed under the Apache License, | ||
* Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. | ||
* | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
pragma "module included by default" | ||
@unstable("The module name 'AutoGpu' is unstable.") | ||
module AutoGpu { | ||
// This module supports GPU-specific attributes like @gpu.assertEligible | ||
// @assertOnGpu. These attributes are translated into calls to procedures | ||
// in this module as part of the loop body, which insert various GPU | ||
// primitives. The primitives are used to configure the GPU execution. | ||
|
||
use ChplConfig; | ||
use Errors; | ||
|
||
inline proc chpl__gpuAssertEligibleAttr() { | ||
if CHPL_LOCALE_MODEL == "gpu" then | ||
__primitive("assert gpu eligible"); | ||
} | ||
|
||
config param silenceAssertOnGpuWarning = false; | ||
|
||
inline proc chpl__assertOnGpuAttr() { | ||
if CHPL_LOCALE_MODEL != "gpu" && !silenceAssertOnGpuWarning { | ||
compilerWarning("@assertOnGpu encountered in non-GPU compilation"); | ||
compilerWarning("this attribute has a runtime component, and will ", | ||
"always halt execution in a non-GPU context."); | ||
compilerWarning("consider using '@gpu.assertEligible' to ensure ", | ||
"that the code can be executed on the GPU without ", | ||
"runtime checks."); | ||
} | ||
__primitive("chpl_assert_on_gpu", true); | ||
} | ||
|
||
inline proc chpl__gpuBlockSizeAttr(param counter: int, arg: integral) { | ||
if CHPL_LOCALE_MODEL == "gpu" then | ||
__primitive("gpu set blockSize", arg, counter); | ||
} | ||
|
||
pragma "last resort" | ||
inline proc chpl__gpuBlockSizeAttr(param counter: int, rest ...) { | ||
compilerError("'@gpu.blockSize' attribute must have exactly one argument: an integral value for the block size"); | ||
} | ||
|
||
pragma "last resort" | ||
inline proc chpl__gpuBlockSizeAttr(param counter: int) { | ||
compilerError("'@gpu.blockSize' attribute must have exactly one argument: an integral value for the block size"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
@gpu.assertEligible | ||
var A = foreach i in 1..100 do i; | ||
|
||
writeln("all is good; '@gpu.assertEligible' doesn't require GPU execution."); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
all is good; '@gpu.assertEligible' doesn't require GPU execution. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
assertOnNotGpuEligible.chpl:15: In function 'funcMarkedNotGpuizableThatTriesToGpuize': | ||
assertOnNotGpuEligible.chpl:17: error: Loop is marked with @gpu.assertEligible but is not eligible for execution on a GPU | ||
assertOnNotGpuEligible.chpl:15: note: parent function disallows execution on a GPU |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
assertOnNotGpuEligible.chpl:32: error: Loop is marked with @gpu.assertEligible but is not eligible for execution on a GPU | ||
assertOnNotGpuEligible.chpl:23: note: function is marked as not eligible for GPU execution | ||
assertOnNotGpuEligible.chpl:33: note: reached via call to 'funcMarkedNotGpuizable' in loop body here |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
assertOnNotGpuEligible.chpl:39: error: Loop is marked with @gpu.assertEligible but is not eligible for execution on a GPU | ||
assertOnNotGpuEligible.chpl:12: note: called function has outer var access | ||
assertOnNotGpuEligible.chpl:40: note: reached via call to 'usesOutsideVar' in loop body here |
Empty file.
Oops, something went wrong.