-
Notifications
You must be signed in to change notification settings - Fork 2
Wrote some basic tests for kokkos-implicit-this-capture #5
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
#pragma once | ||
|
||
// | ||
// Standard library stuff that shows up in Kokkos | ||
// | ||
namespace std { | ||
struct string { | ||
string(const char *); | ||
~string(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you need to bother with the destructor? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I copy pasted this from a different check, we can remove it. The mocking is specifically not finalized, I am just trying to get it working and will expand it as needed. |
||
}; | ||
} // namespace std | ||
|
||
// | ||
// Global things that show up in Kokkos | ||
// | ||
using size_t = decltype(sizeof(int)); | ||
int printf(const char *format, ...); | ||
|
||
// | ||
// Kokkos macros | ||
// | ||
#define KOKKOS_LAMBDA [=] | ||
#define KOKKOS_FUNCTION __attribute__((annotate("KOKKOS_FUNCTION"))) | ||
#define KOKKOS_INLINE_FUNCTION __attribute__((annotate("KOKKOS_INLINE_FUNCTION"))) | ||
#define KOKKOS_FORCEINLINE_FUNCTION __attribute__((annotate("KOKKOS_FORCEINLINE_FUNCTION"))) | ||
|
||
// | ||
// Kokkos public and semi-public API | ||
// | ||
namespace Kokkos { | ||
namespace Impl { | ||
template <typename IndexType, typename MemberType> | ||
struct TeamThreadRangeBoundariesStruct { | ||
KOKKOS_INLINE_FUNCTION | ||
TeamThreadRangeBoundariesStruct(MemberType const &m, | ||
IndexType const &arg_end) {} | ||
}; | ||
|
||
template <typename IndexType, typename MemberType> | ||
struct ThreadVectorRangeBoundariesStruct { | ||
KOKKOS_INLINE_FUNCTION | ||
ThreadVectorRangeBoundariesStruct(MemberType const &m, | ||
IndexType const &arg_end) {} | ||
}; | ||
} // namespace Impl | ||
|
||
template <class FunctorType> | ||
inline void parallel_for(const size_t work_count, | ||
const FunctorType &functor, | ||
const std::string &str = "") {} | ||
|
||
template <class ExecPolicy, class FunctorType> | ||
inline void parallel_for(const std::string &str, | ||
const ExecPolicy &policy, | ||
const FunctorType &functor) {} | ||
|
||
template <class ExecPolicy, class FunctorType> | ||
inline void parallel_for(const ExecPolicy &policy, | ||
const FunctorType &functor, | ||
std::string const &str = "") {} | ||
|
||
template <class... Properties> | ||
class TeamPolicy { | ||
public: | ||
using member_type = int; | ||
}; | ||
|
||
template <typename iType> | ||
KOKKOS_INLINE_FUNCTION | ||
Impl::TeamThreadRangeBoundariesStruct<iType, TeamPolicy<>::member_type> | ||
TeamThreadRange(const TeamPolicy<>::member_type &thread, iType count) { | ||
return Impl::TeamThreadRangeBoundariesStruct<iType, | ||
TeamPolicy<>::member_type>(thread, count); | ||
} | ||
|
||
template <typename iType> | ||
KOKKOS_INLINE_FUNCTION | ||
Impl::ThreadVectorRangeBoundariesStruct<iType, TeamPolicy<>::member_type> | ||
ThreadVectorRange(const TeamPolicy<>::member_type &thread, iType count) { | ||
return Impl::ThreadVectorRangeBoundariesStruct<iType, | ||
TeamPolicy<>::member_type>(thread, count); | ||
} | ||
|
||
namespace Impl { | ||
struct SomeHostExecutionSpace {}; | ||
|
||
template <typename... Properties> | ||
struct PolicyTraits{}; | ||
} // namespace Impl | ||
|
||
using DefaultExecutionSpace = Impl::SomeHostExecutionSpace; | ||
using DefaultHostExecutionSpace = Impl::SomeHostExecutionSpace; | ||
|
||
template <class... Properties> | ||
class RangePolicy : public Impl::PolicyTraits<Properties...>{ | ||
public: | ||
RangePolicy(int, int) {} | ||
}; | ||
|
||
} // namespace Kokkos |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// RUN: %check_clang_tidy %s kokkos-implicit-this-capture %t -- -config="{CheckOptions: [{key: kokkos-implicit-this-capture.CheckIfExplicitHost, value: 1}]}" -header-filter=.* -system-headers -- -isystem %S/Inputs/kokkos/ | ||
|
||
#include "Kokkos_Core_mock.h" | ||
|
||
KOKKOS_FUNCTION void do_something(int x) { printf("Got int %d\n", x); } | ||
|
||
class BadClass { | ||
int MyInt = 0; | ||
|
||
public: | ||
void capturesThis() { | ||
Kokkos::parallel_for( | ||
Kokkos::RangePolicy<Kokkos::DefaultExecutionSpace>(0,10), | ||
[=](int) { do_something(MyInt); }); | ||
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: Lambda passed to parallel_for implicitly captures this. [kokkos-implicit-this-capture] | ||
} | ||
}; | ||
|
||
class GoodClass { | ||
int MyInt = 0; | ||
|
||
public: | ||
void capturesThis() { | ||
Kokkos::parallel_for( | ||
Kokkos::RangePolicy<Kokkos::DefaultHostExecutionSpace>(0,10), | ||
KOKKOS_LAMBDA(int) { do_something(MyInt); }); | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,34 @@ | ||
// RUN: %check_clang_tidy %s kokkos-implicit-this-capture %t | ||
// RUN: %check_clang_tidy %s kokkos-implicit-this-capture %t -- -header-filter=.* -system-headers -- -isystem %S/Inputs/kokkos/ | ||
|
||
// TODO Need to mock Kokkos | ||
// FIXME: Add something that triggers the check here. | ||
// void f(); | ||
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'f' is insufficiently awesome [kokkos-implicit-this-capture] | ||
#include "Kokkos_Core_mock.h" | ||
|
||
// FIXME: Verify the applied fix. | ||
// * Make the CHECK patterns specific enough and try to make verified lines | ||
// unique to avoid incorrect matches. | ||
// * Use {{}} for regular expressions. | ||
// CHECK-FIXES: {{^}}void awesome_f();{{$}} | ||
KOKKOS_FUNCTION void do_something(int x) { printf("Got int %d\n", x); } | ||
using TeamMember = Kokkos::TeamPolicy<>::member_type; | ||
class BadClass { | ||
int my_int; | ||
|
||
// FIXME: Add something that doesn't trigger the check here. | ||
// void awesome_f2(); | ||
public: | ||
void capturesThis() { | ||
Kokkos::parallel_for( | ||
10, KOKKOS_LAMBDA(int x) { my_int = x; }); | ||
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: Lambda passed to parallel_for implicitly captures this. [kokkos-implicit-this-capture] | ||
} | ||
}; | ||
|
||
// Should not warn | ||
struct GoodClass { | ||
int foo; | ||
TeamMember member; | ||
|
||
KOKKOS_INLINE_FUNCTION void method() { | ||
auto TTR = Kokkos::TeamThreadRange(member, 15); | ||
Kokkos::parallel_for(TTR, [&](int i) { | ||
auto TVR = Kokkos::ThreadVectorRange(member, 3); | ||
auto func = [&](int j) { | ||
do_something(foo); | ||
do_something(i + j); | ||
}; | ||
Kokkos::parallel_for(TVR, func); | ||
}); | ||
} | ||
}; |
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.
So that the only real change here, right?
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.
There was formatting, and also I changed the string for the regex for
isAllowedPolicy
slightly.