Unverified Commit f28a62ea authored by Paul Fultz II's avatar Paul Fultz II Committed by GitHub
Browse files

Add hip clang builds to jenkins (#651)

* Make global variables const

* Tidy fixes

* Disable some lints

* Formatting

* Fix tidy const

* Formatting

* Add missing const keywords

* Formatting

* More fixes

* Fix remaining tidy issues

* Formatting

* Fix rocblas function call

* Formatting

* Fix nodiscard warnings

* Formatting

* Use named parameters

* Remove overload

* Add overload

* Remove noncps

* Use named param for node

* Add auto register header

* Use named parameters

* Refactor jenkinsfile

* Fix shadow

* Add missing body variable

* Add more const methods

* Add hip-clang docker builds

* Remove comments

* Add clang-format

* Add more const

* Formatting

* Rename stage

* Disable check

* Add another const

* Add python 2 dev packages

* Add sphinx to dockerfile
parent 48fa934d
...@@ -17,7 +17,7 @@ inline namespace MIGRAPHX_INLINE_NS { ...@@ -17,7 +17,7 @@ inline namespace MIGRAPHX_INLINE_NS {
void run_passes(program& prog, const std::vector<pass>& passes, tracer trace) void run_passes(program& prog, const std::vector<pass>& passes, tracer trace)
{ {
for(auto& p : passes) for(const auto& p : passes)
{ {
trace("Pass: ", p.name()); trace("Pass: ", p.name());
p.apply(prog); p.apply(prog);
......
...@@ -191,7 +191,7 @@ instruction_ref program::insert_instruction(instruction_ref ins, ...@@ -191,7 +191,7 @@ instruction_ref program::insert_instruction(instruction_ref ins,
instruction_ref program::replace_instruction(instruction_ref ins, instruction_ref program::replace_instruction(instruction_ref ins,
const operation& op, const operation& op,
std::vector<instruction_ref> args) std::vector<instruction_ref> args) MIGRAPHX_TIDY_CONST
{ {
assert(std::all_of( assert(std::all_of(
args.begin(), args.end(), [&](instruction_ref x) { return has_instruction(x); }) && args.begin(), args.end(), [&](instruction_ref x) { return has_instruction(x); }) &&
...@@ -394,7 +394,7 @@ std::vector<shape> program::get_output_shapes() const ...@@ -394,7 +394,7 @@ std::vector<shape> program::get_output_shapes() const
auto last_ins = impl->instructions.back(); auto last_ins = impl->instructions.back();
if(last_ins.name() == "@return") if(last_ins.name() == "@return")
{ {
auto& output_ins = last_ins.inputs(); const auto& output_ins = last_ins.inputs();
std::vector<shape> output_shapes; std::vector<shape> output_shapes;
std::transform(output_ins.begin(), std::transform(output_ins.begin(),
output_ins.end(), output_ins.end(),
......
...@@ -6,7 +6,7 @@ inline namespace MIGRAPHX_INLINE_NS { ...@@ -6,7 +6,7 @@ inline namespace MIGRAPHX_INLINE_NS {
std::unordered_map<std::string, operation>& op_map() std::unordered_map<std::string, operation>& op_map()
{ {
static std::unordered_map<std::string, operation> m; static std::unordered_map<std::string, operation> m; // NOLINT
return m; return m;
} }
void register_op(const operation& op) { op_map()[op.name()] = op; } void register_op(const operation& op) { op_map()[op.name()] = op; }
......
...@@ -6,7 +6,7 @@ inline namespace MIGRAPHX_INLINE_NS { ...@@ -6,7 +6,7 @@ inline namespace MIGRAPHX_INLINE_NS {
std::unordered_map<std::string, target>& target_map() std::unordered_map<std::string, target>& target_map()
{ {
static std::unordered_map<std::string, target> m; static std::unordered_map<std::string, target> m; // NOLINT
return m; return m;
} }
......
...@@ -332,7 +332,7 @@ struct stream_info ...@@ -332,7 +332,7 @@ struct stream_info
} }
std::unordered_map<instruction_ref, std::vector<std::vector<instruction_ref>>> std::unordered_map<instruction_ref, std::vector<std::vector<instruction_ref>>>
find_concurrent_instructions(program& p) find_concurrent_instructions(program& p) const
{ {
std::unordered_map<instruction_ref, std::vector<std::vector<instruction_ref>>> result; std::unordered_map<instruction_ref, std::vector<std::vector<instruction_ref>>> result;
std::unordered_map<instruction_ref, std::unordered_set<instruction_ref>> merge_from; std::unordered_map<instruction_ref, std::unordered_set<instruction_ref>> merge_from;
...@@ -350,7 +350,7 @@ struct stream_info ...@@ -350,7 +350,7 @@ struct stream_info
auto streams = this->get_streams(ins); auto streams = this->get_streams(ins);
// Collect concur instructions for each merge point. // Collect concur instructions for each merge point.
for(auto& merge : merge_from[ins]) for(const auto& merge : merge_from[ins])
{ {
for(auto stream : streams) for(auto stream : streams)
{ {
......
...@@ -15,7 +15,7 @@ struct shape_impl ...@@ -15,7 +15,7 @@ struct shape_impl
{ {
static std::shared_ptr<shape_impl> default_shape() static std::shared_ptr<shape_impl> default_shape()
{ {
static std::shared_ptr<shape_impl> result = std::make_shared<shape_impl>(); static const std::shared_ptr<shape_impl> result = std::make_shared<shape_impl>();
return result; return result;
} }
...@@ -235,7 +235,7 @@ std::ostream& operator<<(std::ostream& os, const shape& x) ...@@ -235,7 +235,7 @@ std::ostream& operator<<(std::ostream& os, const shape& x)
shape::type_t shape::parse_type(const std::string& s) shape::type_t shape::parse_type(const std::string& s)
{ {
static std::unordered_map<std::string, shape::type_t> m = { static const std::unordered_map<std::string, shape::type_t> m = {
#define MIGRAPHX_SHAPE_GENERATE_TYPE_STRING_MAP(x, t) {#x, x}, {#t, x}, #define MIGRAPHX_SHAPE_GENERATE_TYPE_STRING_MAP(x, t) {#x, x}, {#t, x},
MIGRAPHX_SHAPE_VISIT_TYPES(MIGRAPHX_SHAPE_GENERATE_TYPE_STRING_MAP)}; MIGRAPHX_SHAPE_VISIT_TYPES(MIGRAPHX_SHAPE_GENERATE_TYPE_STRING_MAP)};
return m.at(s); return m.at(s);
......
...@@ -939,7 +939,7 @@ struct cpu_apply ...@@ -939,7 +939,7 @@ struct cpu_apply
} }
} }
void apply_cpu_op(instruction_ref ins) void apply_cpu_op(instruction_ref ins) const
{ {
prog->replace_instruction(ins, cpu_op{ins->get_operator()}, ins->inputs()); prog->replace_instruction(ins, cpu_op{ins->get_operator()}, ins->inputs());
} }
...@@ -957,7 +957,7 @@ struct cpu_apply ...@@ -957,7 +957,7 @@ struct cpu_apply
prog->replace_instruction(ins, T{op}, ins->inputs()); prog->replace_instruction(ins, T{op}, ins->inputs());
} }
void apply_pooling(instruction_ref ins) void apply_pooling(instruction_ref ins) const
{ {
auto&& op = any_cast<op::pooling>(ins->get_operator()); auto&& op = any_cast<op::pooling>(ins->get_operator());
if(op.mode == "max") if(op.mode == "max")
......
...@@ -214,6 +214,7 @@ rocm_set_soversion(migraphx_gpu ${MIGRAPHX_SO_VERSION}) ...@@ -214,6 +214,7 @@ rocm_set_soversion(migraphx_gpu ${MIGRAPHX_SO_VERSION})
rocm_clang_tidy_check(migraphx_gpu) rocm_clang_tidy_check(migraphx_gpu)
# Workaround broken rocblas headers # Workaround broken rocblas headers
target_compile_definitions(migraphx_gpu PUBLIC -D__HIP_PLATFORM_HCC__=1) target_compile_definitions(migraphx_gpu PUBLIC -D__HIP_PLATFORM_HCC__=1)
target_compile_options(migraphx_gpu PRIVATE -std=c++17)
target_link_libraries(migraphx_gpu PUBLIC migraphx MIOpen roc::rocblas) target_link_libraries(migraphx_gpu PUBLIC migraphx MIOpen roc::rocblas)
target_link_libraries(migraphx_gpu PRIVATE migraphx_device) target_link_libraries(migraphx_gpu PRIVATE migraphx_device)
......
...@@ -13,7 +13,7 @@ namespace device { ...@@ -13,7 +13,7 @@ namespace device {
argument gather(hipStream_t stream, argument result, argument arg1, argument arg2, int axis) argument gather(hipStream_t stream, argument result, argument arg1, argument arg2, int axis)
{ {
auto axis_index = (axis < 0) ? (axis + arg1.get_shape().lens().size()) : axis; auto axis_index = (axis < 0) ? (axis + arg1.get_shape().lens().size()) : axis;
auto& input_shape = arg1.get_shape(); const auto& input_shape = arg1.get_shape();
auto lens = input_shape.lens(); auto lens = input_shape.lens();
auto axis_dim_size = lens[axis_index]; auto axis_dim_size = lens[axis_index];
lens[axis_index] = arg2.get_shape().elements(); lens[axis_index] = arg2.get_shape().elements();
......
...@@ -44,7 +44,7 @@ struct index ...@@ -44,7 +44,7 @@ struct index
template <class F> template <class F>
__global__ void launcher(F f) __global__ void launcher(F f)
{ {
index idx{blockIdx.x * blockDim.x + threadIdx.x, threadIdx.x, blockIdx.x}; index idx{blockIdx.x * blockDim.x + threadIdx.x, threadIdx.x, blockIdx.x}; // NOLINT
f(idx); f(idx);
} }
...@@ -84,6 +84,9 @@ inline auto gs_launch(hipStream_t stream, index_int n, index_int local = 1024) ...@@ -84,6 +84,9 @@ inline auto gs_launch(hipStream_t stream, index_int n, index_int local = 1024)
}; };
} }
#ifdef MIGRAPHX_USE_CLANG_TIDY
#define MIGRAPHX_DEVICE_SHARED
#else
// Workaround hcc's broken tile_static macro // Workaround hcc's broken tile_static macro
#ifdef tile_static #ifdef tile_static
#undef tile_static #undef tile_static
...@@ -91,6 +94,7 @@ inline auto gs_launch(hipStream_t stream, index_int n, index_int local = 1024) ...@@ -91,6 +94,7 @@ inline auto gs_launch(hipStream_t stream, index_int n, index_int local = 1024)
#else #else
#define MIGRAPHX_DEVICE_SHARED __shared__ #define MIGRAPHX_DEVICE_SHARED __shared__
#endif #endif
#endif
} // namespace device } // namespace device
} // namespace gpu } // namespace gpu
......
...@@ -26,6 +26,15 @@ rocblas_datatype get_type(shape::type_t type) ...@@ -26,6 +26,15 @@ rocblas_datatype get_type(shape::type_t type)
MIGRAPHX_THROW("ROCBLAS_GEMM: data type not supported!"); MIGRAPHX_THROW("ROCBLAS_GEMM: data type not supported!");
} }
template <class R, class... Ts, class... Us>
R rocblas_invoke(R (*f)(Ts...), Us... xs)
{
if constexpr(sizeof...(Ts) == sizeof...(Us))
return f(xs...);
else
return f(xs..., nullptr, nullptr);
}
template <class T> template <class T>
void gemm_impl( void gemm_impl(
context& ctx, const shape& output_shape, const std::vector<argument>& args, T alpha, T beta) context& ctx, const shape& output_shape, const std::vector<argument>& args, T alpha, T beta)
...@@ -75,7 +84,8 @@ void gemm_impl( ...@@ -75,7 +84,8 @@ void gemm_impl(
// column-major format. When doing a C = A * B, we actually do // column-major format. When doing a C = A * B, we actually do
// C^T = (B^T) * (A^T). That is the reason we input args[1] as // C^T = (B^T) * (A^T). That is the reason we input args[1] as
// A and args[0] as B in calling the rocblas_gemm. // A and args[0] as B in calling the rocblas_gemm.
rocblas_gemm_ex(ctx.get_stream().get_rocblas(), rocblas_invoke(&rocblas_gemm_ex,
ctx.get_stream().get_rocblas(),
transb ? rocblas_operation_transpose : rocblas_operation_none, transb ? rocblas_operation_transpose : rocblas_operation_none,
transa ? rocblas_operation_transpose : rocblas_operation_none, transa ? rocblas_operation_transpose : rocblas_operation_none,
n, n,
...@@ -98,13 +108,11 @@ void gemm_impl( ...@@ -98,13 +108,11 @@ void gemm_impl(
compute_type, compute_type,
rocblas_gemm_algo_standard, rocblas_gemm_algo_standard,
0, 0,
0, 0);
nullptr,
nullptr);
} }
else else
{ {
rocblas_gemm_strided_batched_ex( rocblas_invoke(&rocblas_gemm_strided_batched_ex,
ctx.get_stream().get_rocblas(), ctx.get_stream().get_rocblas(),
transb ? rocblas_operation_transpose : rocblas_operation_none, transb ? rocblas_operation_transpose : rocblas_operation_none,
transa ? rocblas_operation_transpose : rocblas_operation_none, transa ? rocblas_operation_transpose : rocblas_operation_none,
...@@ -133,9 +141,7 @@ void gemm_impl( ...@@ -133,9 +141,7 @@ void gemm_impl(
compute_type, compute_type,
rocblas_gemm_algo_standard, rocblas_gemm_algo_standard,
0, 0,
0, 0);
nullptr,
nullptr);
} }
}); });
} }
......
...@@ -139,7 +139,12 @@ void set_device(std::size_t id) ...@@ -139,7 +139,12 @@ void set_device(std::size_t id)
MIGRAPHX_THROW("Error setting device"); MIGRAPHX_THROW("Error setting device");
} }
void gpu_sync() { hipDeviceSynchronize(); } void gpu_sync()
{
auto status = hipDeviceSynchronize();
if(status != hipSuccess)
MIGRAPHX_THROW("hip device synchronization failed: " + hip_error(status));
}
void hip_async_copy(context& ctx, const argument& src, const argument& dst, hipMemcpyKind kind) void hip_async_copy(context& ctx, const argument& src, const argument& dst, hipMemcpyKind kind)
{ {
......
...@@ -37,7 +37,7 @@ struct hip_device ...@@ -37,7 +37,7 @@ struct hip_device
stream(std::size_t device_number) : id(device_number) {} stream(std::size_t device_number) : id(device_number) {}
void setup() { set_device(id); } void setup() const { set_device(id); }
static hip_stream_ptr create_stream() static hip_stream_ptr create_stream()
{ {
......
...@@ -78,7 +78,7 @@ void arg_op(Op op, hipStream_t stream, const argument& result, const argument& a ...@@ -78,7 +78,7 @@ void arg_op(Op op, hipStream_t stream, const argument& result, const argument& a
migraphx::shape batch_shape{arg_shape.type(), batch_lens}; migraphx::shape batch_shape{arg_shape.type(), batch_lens};
hip_visit_all(arg, arg_shape, batch_shape)([&](auto input, auto arg_s, auto batch_s) { hip_visit_all(arg, arg_shape, batch_shape)([&](auto input, auto arg_s, auto batch_s) {
auto output = device_cast(result.get<int64_t>().data()); auto* output = device_cast(result.get<int64_t>().data());
using type = device_type<std::remove_cv_t<typename decltype(input)::value_type>>; using type = device_type<std::remove_cv_t<typename decltype(input)::value_type>>;
// use one block for items in one batch. // use one block for items in one batch.
const size_t max_block_size = 256; const size_t max_block_size = 256;
......
...@@ -48,7 +48,7 @@ struct miopen_apply ...@@ -48,7 +48,7 @@ struct miopen_apply
instruction_ref last{}; instruction_ref last{};
std::unordered_map<instruction_ref, std::string> prog_output_names{}; std::unordered_map<instruction_ref, std::string> prog_output_names{};
context& get_context() context& get_context() const
{ {
assert(pass != nullptr); assert(pass != nullptr);
assert(pass->ctx != nullptr); assert(pass->ctx != nullptr);
...@@ -67,7 +67,7 @@ struct miopen_apply ...@@ -67,7 +67,7 @@ struct miopen_apply
this->last = instruction::get_output_alias(std::prev(prog->end())); this->last = instruction::get_output_alias(std::prev(prog->end()));
if(this->last->name() == "@return") if(this->last->name() == "@return")
{ {
auto& prog_outputs = last->inputs(); const auto& prog_outputs = last->inputs();
std::vector<instruction_ref> outputs_alias(prog_outputs.size()); std::vector<instruction_ref> outputs_alias(prog_outputs.size());
std::transform(prog_outputs.begin(), std::transform(prog_outputs.begin(),
...@@ -178,11 +178,11 @@ struct miopen_apply ...@@ -178,11 +178,11 @@ struct miopen_apply
auto ret = std::prev(prog->end()); auto ret = std::prev(prog->end());
if(ret->name() == "@return") if(ret->name() == "@return")
{ {
auto& inputs = ret->inputs(); const auto& inputs = ret->inputs();
// each input of ret need to be copied from gpu to host, and replace // each input of ret need to be copied from gpu to host, and replace
// output with copy output // output with copy output
for(auto& in : inputs) for(const auto& in : inputs)
{ {
auto p_output = prog->insert_instruction(ret, hip_copy_from_gpu{}, in); auto p_output = prog->insert_instruction(ret, hip_copy_from_gpu{}, in);
instruction::replace_argument(ret, in, p_output); instruction::replace_argument(ret, in, p_output);
......
...@@ -26,7 +26,7 @@ struct record_event ...@@ -26,7 +26,7 @@ struct record_event
return {}; return {};
} }
void finalize(context& ctx, const shape&, const std::vector<shape>&) void finalize(context& ctx, const shape&, const std::vector<shape>&) const
{ {
ctx.create_events(event); ctx.create_events(event);
} }
...@@ -66,7 +66,10 @@ struct set_stream ...@@ -66,7 +66,10 @@ struct set_stream
ctx.set_stream(stream); ctx.set_stream(stream);
return {}; return {};
} }
void finalize(context& ctx, const shape&, const std::vector<shape>&) { ctx.set_stream(stream); } void finalize(context& ctx, const shape&, const std::vector<shape>&) const
{
ctx.set_stream(stream);
}
}; };
MIGRAPHX_REGISTER_OP(record_event) MIGRAPHX_REGISTER_OP(record_event)
...@@ -112,7 +115,7 @@ static std::unordered_map<std::string, std::size_t> create_weight_map() ...@@ -112,7 +115,7 @@ static std::unordered_map<std::string, std::size_t> create_weight_map()
static const std::unordered_map<std::string, std::size_t>& weight_map() static const std::unordered_map<std::string, std::size_t>& weight_map()
{ {
static std::unordered_map<std::string, std::size_t> m = create_weight_map(); static const std::unordered_map<std::string, std::size_t> m = create_weight_map();
return m; return m;
} }
......
...@@ -170,7 +170,7 @@ value& value::operator=(std::nullptr_t) ...@@ -170,7 +170,7 @@ value& value::operator=(std::nullptr_t)
bool value::is_array() const { return x ? x->get_type() == array_type : false; } bool value::is_array() const { return x ? x->get_type() == array_type : false; }
const std::vector<value>& value::value::get_array() const const std::vector<value>& value::value::get_array() const
{ {
auto* r = this->if_array(); const auto* r = this->if_array();
assert(r); assert(r);
return *r; return *r;
} }
...@@ -179,7 +179,7 @@ const std::vector<value>* value::if_array() const { return x ? x->if_array() : n ...@@ -179,7 +179,7 @@ const std::vector<value>* value::if_array() const { return x ? x->if_array() : n
bool value::is_object() const { return x ? x->get_type() == object_type : false; } bool value::is_object() const { return x ? x->get_type() == object_type : false; }
const std::vector<value>& value::get_object() const const std::vector<value>& value::get_object() const
{ {
auto* r = this->if_object(); const auto* r = this->if_object();
assert(r); assert(r);
return *r; return *r;
} }
...@@ -236,7 +236,7 @@ value* value::find(const std::string& pkey) { return find_impl(x, pkey); } ...@@ -236,7 +236,7 @@ value* value::find(const std::string& pkey) { return find_impl(x, pkey); }
const value* value::find(const std::string& pkey) const { return find_impl(x, pkey); } const value* value::find(const std::string& pkey) const { return find_impl(x, pkey); }
bool value::contains(const std::string& pkey) const bool value::contains(const std::string& pkey) const
{ {
auto it = find(pkey); const auto* it = find(pkey);
if(it == nullptr) if(it == nullptr)
return false; return false;
if(it == end()) if(it == end())
...@@ -308,7 +308,7 @@ value& value::at(const std::string& pkey) ...@@ -308,7 +308,7 @@ value& value::at(const std::string& pkey)
} }
const value& value::at(const std::string& pkey) const const value& value::at(const std::string& pkey) const
{ {
auto* r = find(pkey); const auto* r = find(pkey);
if(r == nullptr) if(r == nullptr)
MIGRAPHX_THROW("Not an object for field: " + pkey); MIGRAPHX_THROW("Not an object for field: " + pkey);
if(r == end()) if(r == end())
......
...@@ -33,6 +33,7 @@ MIGRAPHX_DECLARE_ENV_VAR(MIGRAPHX_TRACE_GPU_COMPILE) ...@@ -33,6 +33,7 @@ MIGRAPHX_DECLARE_ENV_VAR(MIGRAPHX_TRACE_GPU_COMPILE)
static std::array<std::function<void()>, 2>& handlers() static std::array<std::function<void()>, 2>& handlers()
{ {
// NOLINTNEXTLINE
static std::array<std::function<void()>, 2> r = {}; static std::array<std::function<void()>, 2> r = {};
return r; return r;
}; };
...@@ -57,6 +58,7 @@ struct auto_print ...@@ -57,6 +58,7 @@ struct auto_print
{ {
static void set_terminate_handler(const std::string& name) static void set_terminate_handler(const std::string& name)
{ {
// NOLINTNEXTLINE
static std::string pname; static std::string pname;
pname = name; pname = name;
std::set_terminate(+[] { std::set_terminate(+[] {
...@@ -218,7 +220,7 @@ int auto_register_verify_program() ...@@ -218,7 +220,7 @@ int auto_register_verify_program()
template <class T> template <class T>
struct verify_program struct verify_program
{ {
static int static_register; static const int static_register;
// This typedef ensures that the static member will be instantiated if // This typedef ensures that the static member will be instantiated if
// the class itself is instantiated // the class itself is instantiated
using static_register_type = using static_register_type =
...@@ -226,6 +228,6 @@ struct verify_program ...@@ -226,6 +228,6 @@ struct verify_program
}; };
template <class T> template <class T>
int verify_program<T>::static_register = auto_register_verify_program<T>(); // NOLINT const int verify_program<T>::static_register = auto_register_verify_program<T>(); // NOLINT
#endif #endif
...@@ -10,18 +10,22 @@ ...@@ -10,18 +10,22 @@
template <class Tag> template <class Tag>
struct stowed struct stowed
{ {
// NOLINTNEXTLINE
static typename Tag::type value; static typename Tag::type value;
}; };
template <class Tag> template <class Tag>
// NOLINTNEXTLINE
typename Tag::type stowed<Tag>::value; typename Tag::type stowed<Tag>::value;
template <class Tag, typename Tag::type X> template <class Tag, typename Tag::type X>
struct stow_private struct stow_private
{ {
stow_private() noexcept { stowed<Tag>::value = X; } stow_private() noexcept { stowed<Tag>::value = X; }
// NOLINTNEXTLINE
static stow_private instance; static stow_private instance;
}; };
template <class Tag, typename Tag::type X> template <class Tag, typename Tag::type X>
// NOLINTNEXTLINE
stow_private<Tag, X> stow_private<Tag, X>::instance; stow_private<Tag, X> stow_private<Tag, X>::instance;
template <class C, class T> template <class C, class T>
......
...@@ -262,6 +262,7 @@ string_map parse(std::vector<std::string> as, Keyword keyword) ...@@ -262,6 +262,7 @@ string_map parse(std::vector<std::string> as, Keyword keyword)
inline auto& get_test_cases() inline auto& get_test_cases()
{ {
// NOLINTNEXTLINE
static std::vector<std::pair<std::string, std::function<void()>>> cases; static std::vector<std::pair<std::string, std::function<void()>>> cases;
return cases; return cases;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment