-
Notifications
You must be signed in to change notification settings - Fork 88
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
Fix targets registration on Windows #2866
Conversation
Can we just use the |
Also, we could make __attribute__((constructor)) void load_targets()
{
make_target("ref");
#ifdef HAVE_CPU
make_target("cpu");
#endif
#ifdef HAVE_GPU
make_target("gpu");
#endif
#ifdef HAVE_FPGA
make_target("fpga");
#endif
} |
It is not supported on Windows. It is only applicable to shared objects. |
This will now work on Windows. DLLs are not the same as shared objects. Furthermore, MSVC/Clang on Windows does not recognize the constructor attribute because Windows does not support it. One must implement DllMain() to serve a similar purpose. However, that is more complicated because it is process-attached and thread-attached aware—the auto registration of a target creates thread-local storage, making it unavailable after exiting from a library loading thread. A DLL on Windows should generate and return an execution context to a caller to store the per-process state. |
I managed to simplify the PR and limit the number of required changes. |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## develop #2866 +/- ##
========================================
Coverage 91.97% 91.97%
========================================
Files 489 489
Lines 19390 19390
========================================
Hits 17833 17833
Misses 1557 1557 ☔ View full report in Codecov by Sentry. |
This build is not recommended to merge 🔴 |
🔴bert_large_uncased_fp16: FAILED: MIGraphX is not within tolerance - check verbose output |
Sure, we can write it using standard C++ as well: struct auto_load_targets
{
auto_load_targets()
{
make_target("ref");
#ifdef HAVE_CPU
make_target("cpu");
#endif
#ifdef HAVE_GPU
make_target("gpu");
#endif
#ifdef HAVE_FPGA
make_target("fpga");
#endif
}
};
static auto load_targets = auto_load_targets(); And this does work on windows because that is how we auto register unit tests.
Why would we call |
@pfultz2 it is done |
src/register_target.cpp
Outdated
} | ||
}; | ||
[[maybe_unused]] static auto load_targets = auto_load_targets{}; | ||
} // namespace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to go into a static/object library that we only link in for the tests. This prevents lazy loading the targets.
src/register_target.cpp
Outdated
@@ -44,8 +66,6 @@ std::unordered_map<std::string, target>& target_map() | |||
return m; | |||
} | |||
|
|||
void register_target_init() { (void)target_map(); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dont remove this, I think this was necessary to ensure targets are loaded in some cases.
@@ -66,9 +65,6 @@ struct register_target_action | |||
} | |||
}; | |||
|
|||
template <class T> | |||
using auto_register_target = auto_register<register_target_action, T>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dont remove this, We still want to provide the option to register a target with CRTP.
@causten CodeCov reposts a 0.01% test coverage decrease. However, when I look into the pull request details, it says that the patch is 100% covered. Am I reading it wrong? |
test/CMakeLists.txt
Outdated
@@ -33,7 +33,11 @@ if(MIGRAPHX_DISABLE_LARGE_BUFFER_TESTS) | |||
add_compile_definitions(MIGRAPHX_DISABLE_LARGE_BUFFER_TESTS) | |||
endif() | |||
|
|||
add_library(register_targets STATIC register_target.cpp) | |||
target_link_libraries(register_targets PRIVATE migraphx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need to link migraphx_all_targets
here as well to get the macros defines such as HAVE_GPU
, HAVE_CPU
, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/register_target.cpp
Outdated
@@ -86,16 +84,5 @@ target make_target(const std::string& name) | |||
return it->second; | |||
} | |||
|
|||
std::vector<std::string> get_targets() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function should not be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something is not right; I reverted that change. I will double-check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fixed it.
Unfortunately, automatic target registration does not work on Windows.
The linker will not add a specified DLL as a dependency if at least a symbol from the dynamic library is not used. Therefore, linking to
migrpahx_all_targets
does not link dynamic libraries on Windows as intended.This PR changes automatic registration to runtime manual registration. Registration is done when the target library is loaded by the
register_target()
function exported from the target library. It is called from themigraphx::make_target()
function.