Commit 00d90ca8 authored by Khalique Ahmed's avatar Khalique Ahmed
Browse files

Merge branch 'develop' of https://github.com/ROCmSoftwarePlatform/AMDMIGraphX into mi100_opts

parents 439c0838 ee79e9b7
......@@ -166,19 +166,16 @@ jobs:
# This path is specific to Ubuntu
path: ${{ github.workspace }}/cget
# Look to see if there is a cache hit for the corresponding requirements file
key: ${{ matrix.os }}-cget-2-${{ hashFiles('requirements.txt') }}
key:
${{ matrix.os }}-cget-4-${{ hashFiles('requirements.txt', 'dev-requirements.txt') }}
${{ matrix.os }}-cget-4-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install cget
cget install pfultz2/rocm-recipes
cget ignore ROCmSoftwarePlatform/rocBLAS ROCmSoftwarePlatform/MIOpen
cget install -f requirements.txt
cget install oneapi-src/oneDNN@v1.7
cget install facebook/zstd@v1.4.5 -X subdir -DCMAKE_DIR=build/cmake
cget install ccache@v4.1
pip install https://github.com/RadeonOpenCompute/rbuild/archive/master.tar.gz
rbuild prepare -d cget -s gh
- name: Prepare timestamp
id: cache_timestamp
shell: cmake -P {0}
......@@ -205,19 +202,13 @@ jobs:
run: |
echo "leak:dnnl::impl::malloc" > suppressions.txt
export LSAN_OPTIONS="suppressions=$(pwd)/suppressions.txt"
mkdir build
cd build
cmake .. \
-DCMAKE_C_COMPILER_LAUNCHER=${{ github.workspace }}/cget/bin/ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=${{ github.workspace }}/cget/bin/ccache \
rbuild build -d cget -s gh -t check \
-DCMAKE_BUILD_TYPE=${{matrix.configuration}} \
-DMIGRAPHX_ENABLE_CPU=On \
-DMIGRAPHX_ENABLE_PYTHON=${{matrix.configuration == 'release' && 'On' || 'Off'}} \
-DCMAKE_CXX_FLAGS_DEBUG="-g1 -Os -fdebug-prefix-map=$PWD=. -fdebug-types-section -fno-omit-frame-pointer ${{matrix.os != 'ubuntu-16.04' && '-fsanitize-address-use-after-scope' || ''}} -fsanitize=undefined,address -fno-sanitize-recover=undefined,address" \
-DCMAKE_CXX_FLAGS_CODECOV="-g1 -Og -fdebug-prefix-map=$PWD=. -fdebug-types-section -fprofile-arcs -ftest-coverage -fno-omit-frame-pointer" \
-DCMAKE_EXE_LINKER_FLAGS='-fuse-ld=gold' \
-DCMAKE_SHARED_LINKER_FLAGS='-fuse-ld=gold'
make -j2 check
${{ github.workspace }}/cget/bin/ccache -s
- name: Upload code coverage
......
......@@ -53,6 +53,7 @@ ENV LANG=C.UTF-8
# Install dependencies
ADD dev-requirements.txt /dev-requirements.txt
ADD requirements.txt /requirements.txt
ADD rbuild.ini /rbuild.ini
COPY ./tools/install_prereqs.sh /
RUN /install_prereqs.sh /usr/local / && rm /install_prereqs.sh
......@@ -95,4 +96,5 @@ ENV LD_LIBRARY_PATH=$PREFIX/lib
# Setup ubsan environment to printstacktrace
ENV UBSAN_OPTIONS=print_stacktrace=1
ENV ASAN_OPTIONS=detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
RUN ln -s /opt/rocm/llvm/bin/llvm-symbolizer /usr/bin/llvm-symbolizer
tensorflow==2.4.0
tensorflow==2.5.0
onnxruntime
tokenizers
\ No newline at end of file
......@@ -44,9 +44,6 @@ RUN ldconfig
ENV LC_ALL=C.UTF-8
ENV LANG=C.UTF-8
# Install rbuild
RUN pip3 install https://github.com/RadeonOpenCompute/rbuild/archive/master.tar.gz
# Install yapf
RUN pip3 install yapf==0.28.0
......@@ -57,6 +54,7 @@ RUN pip3 install -r /doc-requirements.txt
# Install dependencies
ADD dev-requirements.txt /dev-requirements.txt
ADD requirements.txt /requirements.txt
ADD rbuild.ini /rbuild.ini
COPY ./tools/install_prereqs.sh /
RUN /install_prereqs.sh /usr/local / && rm /install_prereqs.sh
......
[main]
cxx = ${rocm_path}/llvm/bin/clang++
cc = ${rocm_path}/llvm/bin/clang
deps =
pfultz2/rocm-recipes
-f requirements.txt
[gh]
ignore = danmar/cppcheck
deps =
-f dev-requirements.txt
oneapi-src/oneDNN@v1.7
define =
CMAKE_C_COMPILER_LAUNCHER=${deps_dir}/bin/ccache
CMAKE_CXX_COMPILER_LAUNCHER=${deps_dir}/bin/ccache
MIGRAPHX_ENABLE_CPU=On
[develop]
cxx = ${rocm_path}/llvm/bin/clang++
cc = ${rocm_path}/llvm/bin/clang
deps =
-f dev-requirements.txt
oneapi-src/oneDNN@v1.7
define =
CMAKE_C_COMPILER_LAUNCHER=${deps_dir}/bin/ccache
CMAKE_CXX_COMPILER_LAUNCHER=${deps_dir}/bin/ccache
MIGRAPHX_ENABLE_CPU=On
\ No newline at end of file
......@@ -15,6 +15,7 @@ add_library(migraphx
compile_src.cpp
cpp_generator.cpp
dead_code_elimination.cpp
dom_info.cpp
dynamic_loader.cpp
eliminate_allocation.cpp
eliminate_contiguous.cpp
......@@ -150,6 +151,7 @@ register_migraphx_ops(
sqdiff
sqrt
squeeze
step
sub
tanh
tan
......
#include <migraphx/dom_info.hpp>
#include <migraphx/program.hpp>
#include <migraphx/iterator_for.hpp>
#include <migraphx/erase.hpp>
#include <migraphx/ranges.hpp>
#include <unordered_set>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
bool dominator_info::strictly_dominate(instruction_ref ins1, instruction_ref ins2)
{
if(ins1 == ins2)
return false;
auto iter = ins2idom.find(ins2);
while(iter != ins2idom.end())
{
if(ins1 == iter->second)
return true;
assert(iter != ins2idom.find(iter->second));
iter = ins2idom.find(iter->second);
}
return false;
}
struct module_visitor
{
module* mm;
module& get_nodes() const { return *mm; }
const std::vector<instruction_ref>& get_children(instruction_ref ins) { return ins->inputs(); }
};
template <class Visitor>
dominator_info compute_dominator_generic(Visitor v)
{
dominator_info info;
std::unordered_map<instruction_ref, std::unordered_set<instruction_ref>> instr2_doms;
for(instruction_ref ins : iterator_for(v.get_nodes()))
{
const std::vector<instruction_ref>& children = v.get_children(ins);
if(children.size() == 1)
{
info.ins2idom[ins] = children.front();
instr2_doms[ins].insert(children.front());
}
else if(children.size() > 1)
{
auto&& doms = instr2_doms[ins];
doms = instr2_doms[children.front()];
std::for_each(children.begin() + 1, children.end(), [&](instruction_ref child) {
auto&& child_doms = instr2_doms[child];
erase_if(doms, [&](auto x) { return not contains(child_doms, x); });
});
auto iter = std::find_if(doms.begin(), doms.end(), [&](auto dom1) {
return std::none_of(doms.begin(), doms.end(), [&](auto dom2) {
if(dom1 == dom2)
return false;
return info.strictly_dominate(dom1, dom2);
});
});
if(iter != doms.end())
info.ins2idom[ins] = *iter;
}
instr2_doms[ins].insert(ins);
}
return info;
}
dominator_info compute_dominator(module& m)
{
return compute_dominator_generic(module_visitor{&m});
}
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
......@@ -43,6 +43,7 @@ struct outline
struct param
{
std::string parameter;
uint32_t order = 0;
template <class Self, class F>
static auto reflect(Self& self, F f)
......
#ifndef MIGRAPHX_GUARD_RTGLIB_DOM_INFO_HPP
#define MIGRAPHX_GUARD_RTGLIB_DOM_INFO_HPP
#include <migraphx/config.hpp>
#include <migraphx/instruction.hpp>
#include <unordered_map>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
struct module;
struct dominator_info
{
bool strictly_dominate(instruction_ref ins1, instruction_ref ins2);
std::unordered_map<instruction_ref, instruction_ref> ins2idom;
};
dominator_info compute_dominator(module& m);
// dominator_info compute_dominator_naive(const module& m);
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
#endif
......@@ -25,12 +25,19 @@ auto erase(R&& r, const T& value)
*
* @param r The container to erase elements from
* @param pred Predicate function that selects which elements should be erased.
* @return Returns iterator to erased element
*/
template <class R, class P>
auto erase_if(R&& r, P&& pred)
void erase_if(R&& r, P&& pred)
{
return r.erase(std::remove_if(r.begin(), r.end(), pred), r.end());
auto first = r.begin();
auto last = r.end();
while(first != last)
{
if(pred(*first))
first = r.erase(first);
else
first++;
}
}
} // namespace MIGRAPHX_INLINE_NS
......
......@@ -2,14 +2,15 @@
#define MIGRAPHX_GUARD_RTGLIB_IOTA_ITERATOR_HPP
#include <migraphx/config.hpp>
#include <migraphx/functional.hpp>
#include <iterator>
#include <type_traits>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
template <class F, class Iterator = std::size_t>
struct iota_iterator
template <class F, class Iterator = std::ptrdiff_t>
struct basic_iota_iterator
{
Iterator index;
F f;
......@@ -20,40 +21,40 @@ struct iota_iterator
using pointer = typename std::add_pointer<value_type>::type;
using iterator_category = std::random_access_iterator_tag;
iota_iterator& operator+=(int n)
basic_iota_iterator& operator+=(int n)
{
index += n;
return *this;
}
iota_iterator& operator-=(int n)
basic_iota_iterator& operator-=(int n)
{
index -= n;
return *this;
}
iota_iterator& operator++()
basic_iota_iterator& operator++()
{
index++;
return *this;
}
iota_iterator& operator--()
basic_iota_iterator& operator--()
{
index--;
return *this;
}
iota_iterator operator++(int) // NOLINT
basic_iota_iterator operator++(int) // NOLINT
{
iota_iterator it = *this;
basic_iota_iterator it = *this;
index++;
return it;
}
iota_iterator operator--(int) // NOLINT
basic_iota_iterator operator--(int) // NOLINT
{
iota_iterator it = *this;
basic_iota_iterator it = *this;
index--;
return it;
}
......@@ -61,55 +62,71 @@ struct iota_iterator
reference operator*() const { return f(index); }
};
template <class T, class F>
inline basic_iota_iterator<F, T> make_basic_iota_iterator(T x, F f)
{
return basic_iota_iterator<F, T>{x, f};
}
template <class F, class Iterator>
inline basic_iota_iterator<F, Iterator> operator+(basic_iota_iterator<F, Iterator> x,
std::ptrdiff_t y)
{
return x += y;
}
template <class F, class Iterator>
inline iota_iterator<F, Iterator> operator+(iota_iterator<F, Iterator> x,
iota_iterator<F, Iterator> y)
inline basic_iota_iterator<F, Iterator> operator+(std::ptrdiff_t x,
basic_iota_iterator<F, Iterator> y)
{
return iota_iterator<F, Iterator>(x.index + y.index, x.f);
return y + x;
}
template <class F, class Iterator>
inline std::ptrdiff_t operator-(iota_iterator<F, Iterator> x, iota_iterator<F, Iterator> y)
inline std::ptrdiff_t operator-(basic_iota_iterator<F, Iterator> x,
basic_iota_iterator<F, Iterator> y)
{
return x.index - y.index;
}
template <class F, class Iterator>
inline bool operator==(iota_iterator<F, Iterator> x, iota_iterator<F, Iterator> y)
inline bool operator==(basic_iota_iterator<F, Iterator> x, basic_iota_iterator<F, Iterator> y)
{
return x.index == y.index;
}
template <class F, class Iterator>
inline bool operator!=(iota_iterator<F, Iterator> x, iota_iterator<F, Iterator> y)
inline bool operator!=(basic_iota_iterator<F, Iterator> x, basic_iota_iterator<F, Iterator> y)
{
return x.index != y.index;
}
template <class F, class Iterator>
inline bool operator<(iota_iterator<F, Iterator> x, iota_iterator<F, Iterator> y)
inline bool operator<(basic_iota_iterator<F, Iterator> x, basic_iota_iterator<F, Iterator> y)
{
return x.index < y.index;
}
template <class F, class Iterator>
inline bool operator>(iota_iterator<F, Iterator> x, iota_iterator<F, Iterator> y)
inline bool operator>(basic_iota_iterator<F, Iterator> x, basic_iota_iterator<F, Iterator> y)
{
return x.index > y.index;
}
template <class F, class Iterator>
inline bool operator>=(iota_iterator<F, Iterator> x, iota_iterator<F, Iterator> y)
inline bool operator>=(basic_iota_iterator<F, Iterator> x, basic_iota_iterator<F, Iterator> y)
{
return x.index >= y.index;
}
template <class F, class Iterator>
inline bool operator<=(iota_iterator<F, Iterator> x, iota_iterator<F, Iterator> y)
inline bool operator<=(basic_iota_iterator<F, Iterator> x, basic_iota_iterator<F, Iterator> y)
{
return x.index <= y.index;
}
using iota_iterator = basic_iota_iterator<id>;
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
......
#ifndef MIGRAPHX_GUARD_OPERATORS_STEP_HPP
#define MIGRAPHX_GUARD_OPERATORS_STEP_HPP
#include "migraphx/stringutils.hpp"
#include <array>
#include <migraphx/check_shapes.hpp>
#include <migraphx/argument.hpp>
#include <migraphx/functional.hpp>
#include <migraphx/config.hpp>
#include <cmath>
#include <utility>
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
namespace op {
struct step
{
std::vector<int64_t> axes;
std::vector<int64_t> steps;
template <class Self, class F>
static auto reflect(Self& self, F f)
{
return pack(f(self.axes, "axes"), f(self.steps, "steps"));
}
std::string name() const { return "step"; }
shape compute_shape(std::vector<shape> inputs) const
{
check_shapes{inputs, *this}.has(1);
auto input = inputs.at(0);
auto in_lens = input.lens();
auto t = input.type();
if(axes.size() != steps.size())
{
MIGRAPHX_THROW("STEP: attribute axes {" + to_string_range(axes) +
"} has different dimensions from step {" + to_string_range(steps) +
"}.");
}
if(std::any_of(axes.begin(), axes.end(), [&](auto axis) { return axis >= in_lens.size(); }))
{
MIGRAPHX_THROW("STEP: axis value is out of range!");
}
auto lens = in_lens;
auto strides = input.strides();
for(auto i : range(axes.size()))
{
auto axis = axes[i];
auto step = steps[i];
lens[axis] = (in_lens[axis] + step - 1) / step;
strides[axis] *= step;
}
return {t, lens, strides};
}
argument compute(shape output_shape, std::vector<argument> args) const
{
return args[0].reshape(output_shape);
}
bool is_borrowed() const { return true; }
std::ptrdiff_t output_alias(const std::vector<shape>&) const { return 0; }
};
} // namespace op
} // namespace MIGRAPHX_INLINE_NS
} // namespace migraphx
#endif
......@@ -88,6 +88,7 @@
#include <migraphx/op/sqrt.hpp>
#include <migraphx/op/sqdiff.hpp>
#include <migraphx/op/squeeze.hpp>
#include <migraphx/op/step.hpp>
#include <migraphx/op/sub.hpp>
#include <migraphx/op/tanh.hpp>
#include <migraphx/op/tan.hpp>
......
......@@ -5,6 +5,7 @@
#include <vector>
#include <initializer_list>
#include <migraphx/rank.hpp>
#include <migraphx/iota_iterator.hpp>
#include <migraphx/type_name.hpp>
#include <migraphx/errors.hpp>
#include <migraphx/requires.hpp>
......@@ -208,12 +209,18 @@ struct iterator_range
Iterator end() const { return last; }
};
template <class Iterator>
template <class Iterator, MIGRAPHX_REQUIRES(not std::is_integral<Iterator>{})>
iterator_range<Iterator> range(Iterator start, Iterator last)
{
return {start, last};
}
inline iterator_range<iota_iterator> range(std::ptrdiff_t start, std::ptrdiff_t last)
{
return {{start, {}}, {last, {}}};
}
inline iterator_range<iota_iterator> range(std::ptrdiff_t last) { return range(0, last); }
template <class Iterator>
iterator_range<Iterator> range(std::pair<Iterator, Iterator> p)
{
......
......@@ -35,9 +35,10 @@ struct tensor_view_iterator_read
template <class T>
struct tensor_view
{
using value_type = T;
using iterator = iota_iterator<tensor_view_iterator_read<tensor_view<T>>>;
using const_iterator = iota_iterator<tensor_view_iterator_read<const tensor_view<T>>>;
using value_type = T;
using iterator = basic_iota_iterator<tensor_view_iterator_read<tensor_view<T>>, std::size_t>;
using const_iterator =
basic_iota_iterator<tensor_view_iterator_read<const tensor_view<T>>, std::size_t>;
tensor_view() : m_data(nullptr) {}
tensor_view(shape s, T* d) : m_data(d), m_shape(std::move(s)) {}
......
......@@ -7,13 +7,23 @@
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
struct timer
{
std::chrono::time_point<std::chrono::steady_clock> start = std::chrono::steady_clock::now();
template <class Duration>
auto record() const
{
auto finish = std::chrono::steady_clock::now();
return std::chrono::duration_cast<Duration>(finish - start).count();
}
};
template <class Duration, class F>
auto time(F f)
{
auto start = std::chrono::steady_clock::now();
timer t{};
f();
auto finish = std::chrono::steady_clock::now();
return std::chrono::duration_cast<Duration>(finish - start).count();
return t.record<Duration>();
}
} // namespace MIGRAPHX_INLINE_NS
......
......@@ -25,8 +25,8 @@ struct module_impl
// A list is used to keep references to an instruction stable
std::list<instruction> instructions;
std::unordered_set<instruction*> instruction_set;
std::vector<std::string> input_names;
std::string name;
uint32_t nparams = 0;
bool contains(instruction_ref ins) const
{
......@@ -110,8 +110,7 @@ void module::assign(const module& m)
{
impl->instructions.clear();
}
impl->input_names = m.impl->input_names;
impl->name = m.impl->name;
impl->name = m.impl->name;
std::unordered_map<instruction_ref, instruction_ref> ins_map;
for(auto ins : iterator_for(m))
......@@ -312,9 +311,8 @@ instruction_ref module::add_outline(const shape& s)
instruction_ref module::add_parameter(std::string name, shape s)
{
assert(get_parameter_shape(name) == shape{});
impl->input_names.push_back(name);
impl->push_front({builtin::param{std::move(name)}, std::move(s), {}});
impl->push_front({builtin::param{std::move(name), impl->nparams}, std::move(s), {}});
impl->nparams++;
return impl->instructions.begin();
}
......@@ -350,17 +348,21 @@ shape module::get_parameter_shape(std::string name) const
std::vector<std::string> module::get_parameter_names() const
{
std::vector<std::string> result = impl->input_names;
std::unordered_set<std::string> params;
std::vector<std::string> result;
std::vector<builtin::param> params;
for(auto&& ins : impl->instructions)
{
if(ins.name() == "@param")
{
auto&& name = any_cast<builtin::param>(ins.get_operator()).parameter;
params.insert(name);
auto&& param = any_cast<builtin::param>(ins.get_operator());
params.push_back(param);
}
}
erase_if(result, [&](auto&& name) { return params.count(name) == 0; });
std::stable_sort(
params.begin(), params.end(), by(std::less<>{}, [](auto&& p) { return p.order; }));
std::transform(params.begin(), params.end(), std::back_inserter(result), [&](auto&& p) {
return p.parameter;
});
return result;
}
......
......@@ -249,8 +249,8 @@ void memory_coloring_impl::verify()
if(segment.begin == invalid_offset)
{
if(!interval.is_live_on_entry)
MIGRAPHX_THROW("interval is not live on entry");
// if(!interval.is_live_on_entry)
// MIGRAPHX_THROW("interval is not live on entry");
continue;
}
......
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