Skip to content

[SYCL] Add support for devices white list #867

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

Merged

Conversation

romanovvlad
Copy link
Contributor

@romanovvlad romanovvlad commented Nov 24, 2019

Add support for SYCL_DEVICE_WHITE_LIST config which allows to specify the white
list of devices and their minimum driver version. This is done by setting
configuration in the following format:

DeviceName:{{XXX}},DriverVersion:{{X.Y.Z.W}}|DeviceName:{{XXX}},DriverVersion:{{X.Y.Z.W}}

Where values in {{ }} can be specified in ECMAScript regular expressions
pattern syntax

Devices that do not satisfy the pattern from the white list are ignored.

Signed-off-by: Vlad Romanov [email protected]

};

static std::vector<DevDescT> getWhiteListDesc() {
// TODO: Replace with const char *str =
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Waiting for #859 to resolve this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor

@AlexeySachkov AlexeySachkov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a test

Copy link
Contributor

@asavonic asavonic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a test.

continue;

pi_devices[i] = pi_devices.back();
pi_devices.pop_back();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to change order of devices, right? It should not matter for a properly written program, but can be unexpected. It should be easy to change the loop and iterate forward instead (with two indices: insertion point and current device).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, didn't get the idea how to change the loop.
Furthermore I don't think we should try to preserve the order as program relying on this is 200% invalid. The are source of order change already anyway(icd filenames, OCL_ICD_FILENAMES, OCL_ICD_VENDORS).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should try to preserve the order as program relying on this is 200% invalid.

Relying on the order is invalid, but let's not break it if we can.

The idea is simple: iterate over devices (index i) and have another index where the next "good" device should be written.

int insert_idx = 0;
for (int i = 0; i < devices.size(); ++i) {
  if (isgood(devices[i]) {
    devices[insert_idx++] = devices[i];
  }
}
devices.resize(insert_idx);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, will do.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@romanovvlad romanovvlad force-pushed the private/vromanov/PlatformsWhiteList2 branch from c4ddc85 to cc76e05 Compare November 25, 2019 19:33
@romanovvlad
Copy link
Contributor Author

romanovvlad commented Nov 25, 2019

Don't know how to write a test, do you have some ideas?
The only idea I have is to write the test which, during the first run, prints available device and form some string matching this device, for the second run the string is set as white listed device and test checks that it's really available, for the third run white list is empty and the test verifies that there is no devices available.

@asavonic
Copy link
Contributor

Don't know how to write a test, do you have some ideas?
The only idea I have is to write the test which, during the first run, prints available device and form some string matching this device, for the second run the string is set as white listed device and test checks that it's really available, for the third run white list is empty and the test verifies that there is no devices available.

Sounds good!

@romanovvlad romanovvlad force-pushed the private/vromanov/PlatformsWhiteList2 branch from cc76e05 to 8f879e6 Compare November 26, 2019 09:50
// TODO: Replace with const char *str =
// SYCLConfig<SYCL_DEVICE_WHITE_LIST>::get();
const char *str = getenv("SYCL_DEVICE_WHITE_LIST");
if (!str)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to check this condition as early as possible i.e. before calling filterWhiteList to avoid unnecessary overhead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added additional check before calling filterWhiteList

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to check this condition as early as possible i.e. before calling filterWhiteList to avoid unnecessary overhead.

This is already the first operation in filterWhiteList, which overhead you are trying to avoid?

Copy link
Contributor

@bader bader Nov 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vector creation/deletion + function calls.

Add support for SYCL_DEVICE_WHITE_LIST config which allows to specify the white
list of devices and their minimum driver version. This is done by setting
configuration in the following format:

DeviceName:{{XXX}},DriverVersion:{{X.Y.Z.W}}|DeviceName:{{XXX}},DriverVersion:{{X.Y.Z.W}}

Where values in {{ }} can be specified in ECMAScript regular expressions
pattern syntax

Devices that do not satisfy the pattern from the white list are ignored.

Signed-off-by: Vlad Romanov <[email protected]>
Signed-off-by: Vlad Romanov <[email protected]>
Signed-off-by: Vlad Romanov <[email protected]>
@romanovvlad romanovvlad force-pushed the private/vromanov/PlatformsWhiteList2 branch from 8f879e6 to 98067b0 Compare November 26, 2019 14:37
// Skip ':'
str += 1;

if ('{' != *str || '{' != *(str + 1))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should check that *str != '\0'.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it is actually not needed here.

Signed-off-by: Vlad Romanov <[email protected]>
@romanovvlad
Copy link
Contributor Author

Don't know how to write a test, do you have some ideas?
The only idea I have is to write the test which, during the first run, prints available device and form some string matching this device, for the second run the string is set as white listed device and test checks that it's really available, for the third run white list is empty and the test verifies that there is no devices available.

Sounds good!

Done.

Copy link
Contributor

@asavonic asavonic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@romanovvlad romanovvlad dismissed AlexeySachkov’s stale review November 26, 2019 17:24

All comments are resolved.

@romanovvlad romanovvlad merged commit 4ad5263 into intel:sycl Nov 26, 2019
@romanovvlad romanovvlad deleted the private/vromanov/PlatformsWhiteList2 branch November 26, 2019 17:30
Copy link
Contributor

@keryell keryell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a good introduction about why we need #include <algorithm> :-)
Perhaps https://www.youtube.com/watch?v=pUEnO6SvAMo might be interesting.

// As device name string will be used as regexp pattern, we need to
// get rid of symbols that can be treated in a special way.
// Replace common special symbols with '.' which matches to any sybmol
for (char &Sym : DevName) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about using algorithms instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, will replace with:

std::replace_if(DevName.begin(), DevName.end(),
                       [](const char Sym) { return '(' == Sym || ')' == Sym; }, '.');

Speaking honestly, I think loop code is more readable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking to a simpler:

std::replace(DevName.begin(), DevName.end(), '(', '.');
std::replace(DevName.begin(), DevName.end(), ')', '.');

since everything is in the cache, it should be fast.

Copy link
Contributor Author

@romanovvlad romanovvlad Nov 29, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that it's a test but I don't think we should sacrifice performance in order to make C++ code more readable...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is very subjective.

for (char &Sym : DevName) {
  if (')' == Sym || '(' == Sym)
    Sym = '.';
}

IMO this code is more readable than:

std::replace(DevName.begin(), DevName.end(), '(', '.');
std::replace(DevName.begin(), DevName.end(), ')', '.');

const char driverVerStr[] = "DriverVersion";
decDescs.emplace_back();
while ('\0' != *str) {
const char **valuePtr = nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It smells badly in a C++ code...

throw sycl::runtime_error("Malformed device white list");

++str;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to rewrite this loop in something higher-level so it is more understandable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will try.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants