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

[HIP] Implement coarse-grained memory advice for the HIP adapter #1

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
526f7e6
Remove inline from helper
hdelan Dec 12, 2023
67c3779
AMDGPU enable global variable read write
hdelan Dec 12, 2023
c9fba56
Update source/adapters/hip/enqueue.cpp
hdelan Dec 15, 2023
de02e99
Update source/adapters/hip/enqueue.cpp
hdelan Dec 15, 2023
45d76b7
Refactor read write funcs
hdelan Dec 20, 2023
2e156f7
[EXP][CMDBUF] Add extra event to get CommandBuffer start time
mfrancepillois Nov 3, 2023
e8b7840
Copy command-buffer event timestamps into a dedicated USM memory region.
mfrancepillois Nov 9, 2023
bd25d68
Changes USMShared memory allocation for host only allocation
mfrancepillois Nov 10, 2023
1db8fbf
Fixes event leak
mfrancepillois Nov 13, 2023
35b6a5e
Moves wait-event reset from main CL to suffix CL
mfrancepillois Nov 15, 2023
bdf2918
[UR] Add adapter leak-checking tests
kswiecicki Nov 2, 2023
d6930c7
Add ignore tag to the match.py script
kswiecicki Nov 6, 2023
2e10197
Refactor leak checking match tests
kswiecicki Nov 7, 2023
2317492
[L0][HIP][CUDA] Suppress aborted adapter match tests
kswiecicki Dec 13, 2023
8c63208
[OpenCL] Fix suffixes in adapter match tests
kswiecicki Dec 11, 2023
e1414e1
Merge pull request #1029 from kswiecicki/val-refcount-adapter-fix
kbenzie Jan 11, 2024
d06ba9d
Merge pull request #1035 from Bensuo/cmd-buffer-profiling-l0
kbenzie Jan 11, 2024
25e0b60
Merge pull request #1178 from hdelan/remove-inline-from-helper
aarongreig Jan 12, 2024
79c28d0
Merge pull request #1186 from hdelan/device-global-hip
aarongreig Jan 12, 2024
2530ec6
[HIP] Implement coarse-grained memory advice for the HIP adapter
GeorgeWeb Nov 3, 2023
d8fd5f0
Add new ur_usm_advice_flag_t value for non-coherent memory
GeorgeWeb Jan 10, 2024
a864fb2
Use the designated UR value for coarse-grain memory advise
GeorgeWeb Jan 10, 2024
7fdaed2
Add conformance test for urEnqueueUSMAdvise for non-coherent memory
GeorgeWeb Jan 15, 2024
fd305a5
Fix urEnqueueUSMAdviseTest.NonCoherentDeviceMemorySuccessOrWarning CT…
GeorgeWeb Jan 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 111 additions & 56 deletions cmake/match.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,77 +5,132 @@
# See LICENSE.TXT
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

# check if all lines match in a file
# lines in a match file can contain regex inside of double curly braces {{}}
# Check if all input file content matches match file content.
# Lines in a match file can contain regex inside of double curly braces {{}}.
# Regex patterns are limited to single line.
#
# List of available special tags:
# {{OPT}} - makes content in the same line as the tag optional
# {{IGNORE}} - ignores all content until the next successfully matched line or the end of the input
# Special tags are mutually exclusive and are expected to be located at the start of a line.
#

import os
import sys
import re
from enum import Enum


## @brief print the whole content of input and match files
def print_content(input_lines, match_lines):
def print_content(input_lines, match_lines, ignored_lines):
print("--- Input Lines " + "-" * 64)
print("".join(input_lines).strip())
print("--- Match Lines " + "-" * 64)
print("".join(match_lines).strip())
print("--- Ignored Lines " + "-" * 62)
print("".join(ignored_lines).strip())
print("-" * 80)


if len(sys.argv) != 3:
print("Usage: python match.py <input_file> <match_file>")
sys.exit(1)

input_file = sys.argv[1]
match_file = sys.argv[2]

with open(input_file, 'r') as input, open(match_file, 'r') as match:
input_lines = input.readlines()
match_lines = match.readlines()

if len(match_lines) < len(input_lines):
print(f"Match length < input length (input: {len(input_lines)}, match: {len(match_lines)})")
print_content(input_lines, match_lines)
sys.exit(1)

input_idx = 0
opt = "{{OPT}}"
for i, match_line in enumerate(match_lines):
if match_line.startswith(opt):
optional_line = True
match_line = match_line[len(opt):]
else:
optional_line = False

# split into parts at {{ }}
match_parts = re.split(r'\{{(.*?)\}}', match_line.strip())
pattern = ""
for j, part in enumerate(match_parts):
if j % 2 == 0:
pattern += re.escape(part)
else:
pattern += part
## @brief print the incorrect match line
def print_incorrect_match(match_line, present, expected):
print("Line " + str(match_line) + " does not match")
print("is: " + present)
print("expected: " + expected)

# empty input file or end of input file, from now on match file must be optional
if not input_lines:
if optional_line is True:
continue
else:
print("End of input file or empty file.")
print("expected: " + match_line.strip())

## @brief pattern matching script status values
class Status(Enum):
INPUT_END = 1
MATCH_END = 2
INPUT_AND_MATCH_END = 3
PROCESSING = 4


## @brief check matching script status
def check_status(input_lines, match_lines):
if not input_lines and not match_lines:
return Status.INPUT_AND_MATCH_END
elif not input_lines:
return Status.INPUT_END
elif not match_lines:
return Status.MATCH_END
return Status.PROCESSING


## @brief pattern matching tags.
## Tags are expected to be at the start of the line.
class Tag(Enum):
OPT = "{{OPT}}" # makes the line optional
IGNORE = "{{IGNORE}}" # ignores all input until next match or end of input file


## @brief main function for the match file processing script
def main():
if len(sys.argv) != 3:
print("Usage: python match.py <input_file> <match_file>")
sys.exit(1)

input_file = sys.argv[1]
match_file = sys.argv[2]

with open(input_file, 'r') as input, open(match_file, 'r') as match:
input_lines = input.readlines()
match_lines = match.readlines()

ignored_lines = []

input_idx = 0
match_idx = 0
tags_in_effect = []
while True:
# check file status
status = check_status(input_lines[input_idx:], match_lines[match_idx:])
if (status == Status.INPUT_AND_MATCH_END) or (status == Status.MATCH_END and Tag.IGNORE in tags_in_effect):
# all lines matched or the last line in match file is an ignore tag
sys.exit(0)
elif status == Status.MATCH_END:
print_incorrect_match(match_idx + 1, input_lines[input_idx].strip(), "");
print_content(input_lines, match_lines, ignored_lines)
sys.exit(1)

input_line = input_lines[input_idx].strip()
if not re.fullmatch(pattern, input_line):
if optional_line is True:
continue
input_line = input_lines[input_idx].strip() if input_idx < len(input_lines) else ""
match_line = match_lines[match_idx]

# check for tags
if match_line.startswith(Tag.OPT.value):
tags_in_effect.append(Tag.OPT)
match_line = match_line[len(Tag.OPT.value):]
elif match_line.startswith(Tag.IGNORE.value):
tags_in_effect.append(Tag.IGNORE)
match_idx += 1
continue # line with ignore tag should be skipped

# split into parts at {{ }}
match_parts = re.split(r'\{{(.*?)\}}', match_line.strip())
pattern = ""
for j, part in enumerate(match_parts):
if j % 2 == 0:
pattern += re.escape(part)
else:
pattern += part

# match or process tags
if re.fullmatch(pattern, input_line):
input_idx += 1
match_idx += 1
tags_in_effect = []
elif Tag.OPT in tags_in_effect:
match_idx += 1
tags_in_effect.remove(Tag.OPT)
elif Tag.IGNORE in tags_in_effect:
ignored_lines.append(input_line + os.linesep)
input_idx += 1
else:
print("Line " + str(i+1) + " does not match")
print("is: " + input_line)
print("expected: " + match_line.strip())
print_content(input_lines, match_lines)
print_incorrect_match(match_idx + 1, input_line, match_line.strip())
print_content(input_lines, match_lines, ignored_lines)
sys.exit(1)
else:
if (input_idx == len(input_lines) - 1):
input_lines = []
else:
input_idx += 1


if __name__ == "__main__":
main()
5 changes: 4 additions & 1 deletion include/ur_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -3235,13 +3235,16 @@ typedef enum ur_usm_advice_flag_t {
UR_USM_ADVICE_FLAG_CLEAR_ACCESSED_BY_HOST = UR_BIT(12), ///< Removes the affect of ::UR_USM_ADVICE_FLAG_SET_ACCESSED_BY_HOST
UR_USM_ADVICE_FLAG_SET_PREFERRED_LOCATION_HOST = UR_BIT(13), ///< Hint that the preferred memory location is the host
UR_USM_ADVICE_FLAG_CLEAR_PREFERRED_LOCATION_HOST = UR_BIT(14), ///< Removes the affect of ::UR_USM_ADVICE_FLAG_SET_PREFERRED_LOCATION_HOST
UR_USM_ADVICE_FLAG_SET_NON_COHERENT_MEMORY = UR_BIT(15), ///< Hint that memory coherence will be coarse-grained (up-to-date only at
///< kernel boundaries)
UR_USM_ADVICE_FLAG_CLEAR_NON_COHERENT_MEMORY = UR_BIT(16), ///< Removes the affect of ::UR_USM_ADVICE_FLAG_SET_NON_COHERENT_MEMORY
/// @cond
UR_USM_ADVICE_FLAG_FORCE_UINT32 = 0x7fffffff
/// @endcond

} ur_usm_advice_flag_t;
/// @brief Bit Mask for validating ur_usm_advice_flags_t
#define UR_USM_ADVICE_FLAGS_MASK 0xffff8000
#define UR_USM_ADVICE_FLAGS_MASK 0xfffe0000

///////////////////////////////////////////////////////////////////////////////
/// @brief Handle of USM pool
Expand Down
26 changes: 26 additions & 0 deletions include/ur_print.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6277,6 +6277,12 @@ inline std::ostream &operator<<(std::ostream &os, ur_usm_advice_flag_t value) {
case UR_USM_ADVICE_FLAG_CLEAR_PREFERRED_LOCATION_HOST:
os << "UR_USM_ADVICE_FLAG_CLEAR_PREFERRED_LOCATION_HOST";
break;
case UR_USM_ADVICE_FLAG_SET_NON_COHERENT_MEMORY:
os << "UR_USM_ADVICE_FLAG_SET_NON_COHERENT_MEMORY";
break;
case UR_USM_ADVICE_FLAG_CLEAR_NON_COHERENT_MEMORY:
os << "UR_USM_ADVICE_FLAG_CLEAR_NON_COHERENT_MEMORY";
break;
default:
os << "unknown enumerator";
break;
Expand Down Expand Up @@ -6441,6 +6447,26 @@ inline ur_result_t printFlag<ur_usm_advice_flag_t>(std::ostream &os, uint32_t fl
}
os << UR_USM_ADVICE_FLAG_CLEAR_PREFERRED_LOCATION_HOST;
}

if ((val & UR_USM_ADVICE_FLAG_SET_NON_COHERENT_MEMORY) == (uint32_t)UR_USM_ADVICE_FLAG_SET_NON_COHERENT_MEMORY) {
val ^= (uint32_t)UR_USM_ADVICE_FLAG_SET_NON_COHERENT_MEMORY;
if (!first) {
os << " | ";
} else {
first = false;
}
os << UR_USM_ADVICE_FLAG_SET_NON_COHERENT_MEMORY;
}

if ((val & UR_USM_ADVICE_FLAG_CLEAR_NON_COHERENT_MEMORY) == (uint32_t)UR_USM_ADVICE_FLAG_CLEAR_NON_COHERENT_MEMORY) {
val ^= (uint32_t)UR_USM_ADVICE_FLAG_CLEAR_NON_COHERENT_MEMORY;
if (!first) {
os << " | ";
} else {
first = false;
}
os << UR_USM_ADVICE_FLAG_CLEAR_NON_COHERENT_MEMORY;
}
if (val != 0) {
std::bitset<32> bits(val);
if (!first) {
Expand Down
6 changes: 6 additions & 0 deletions scripts/core/usm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ etors:
- name: CLEAR_PREFERRED_LOCATION_HOST
value: "$X_BIT(14)"
desc: "Removes the affect of $X_USM_ADVICE_FLAG_SET_PREFERRED_LOCATION_HOST"
- name: SET_NON_COHERENT_MEMORY
value: "$X_BIT(15)"
desc: "Hint that memory coherence will be coarse-grained (up-to-date only at kernel boundaries)"
- name: CLEAR_NON_COHERENT_MEMORY
value: "$X_BIT(16)"
desc: "Removes the affect of $X_USM_ADVICE_FLAG_SET_NON_COHERENT_MEMORY"
--- #--------------------------------------------------------------------------
type: handle
desc: "Handle of USM pool"
Expand Down
Loading