Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
MIGraphX
Commits
2ba401f0
Unverified
Commit
2ba401f0
authored
Jul 28, 2022
by
Ted Themistokleous
Committed by
GitHub
Jul 28, 2022
Browse files
Merge branch 'simplify_1_mul_div_ops' into divide_by_zero_check
parents
a330d428
8398fb19
Changes
183
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1094 additions
and
371 deletions
+1094
-371
src/targets/gpu/include/migraphx/gpu/int8_gemm_pack.hpp
src/targets/gpu/include/migraphx/gpu/int8_gemm_pack.hpp
+1
-0
src/targets/gpu/include/migraphx/gpu/mlir.hpp
src/targets/gpu/include/migraphx/gpu/mlir.hpp
+50
-0
src/targets/gpu/include/migraphx/gpu/quant_convolution.hpp
src/targets/gpu/include/migraphx/gpu/quant_convolution.hpp
+2
-2
src/targets/gpu/jit/mlir.cpp
src/targets/gpu/jit/mlir.cpp
+58
-0
src/targets/gpu/jit/softmax.cpp
src/targets/gpu/jit/softmax.cpp
+107
-0
src/targets/gpu/kernels/include/migraphx/kernels/array.hpp
src/targets/gpu/kernels/include/migraphx/kernels/array.hpp
+8
-0
src/targets/gpu/kernels/include/migraphx/kernels/functional.hpp
...rgets/gpu/kernels/include/migraphx/kernels/functional.hpp
+1
-1
src/targets/gpu/kernels/include/migraphx/kernels/index.hpp
src/targets/gpu/kernels/include/migraphx/kernels/index.hpp
+36
-13
src/targets/gpu/kernels/include/migraphx/kernels/preload.hpp
src/targets/gpu/kernels/include/migraphx/kernels/preload.hpp
+2
-1
src/targets/gpu/kernels/include/migraphx/kernels/reduce.hpp
src/targets/gpu/kernels/include/migraphx/kernels/reduce.hpp
+34
-0
src/targets/gpu/kernels/include/migraphx/kernels/shape.hpp
src/targets/gpu/kernels/include/migraphx/kernels/shape.hpp
+1
-0
src/targets/gpu/kernels/include/migraphx/kernels/softmax.hpp
src/targets/gpu/kernels/include/migraphx/kernels/softmax.hpp
+45
-0
src/targets/gpu/kernels/include/migraphx/kernels/vec.hpp
src/targets/gpu/kernels/include/migraphx/kernels/vec.hpp
+2
-0
src/targets/gpu/lowering.cpp
src/targets/gpu/lowering.cpp
+2
-3
src/targets/gpu/mlir.cpp
src/targets/gpu/mlir.cpp
+647
-0
src/targets/gpu/mlir_conv.cpp
src/targets/gpu/mlir_conv.cpp
+0
-315
src/targets/gpu/quant_convolution.cpp
src/targets/gpu/quant_convolution.cpp
+61
-21
src/targets/gpu/target.cpp
src/targets/gpu/target.cpp
+5
-3
src/tf/tf_parser.cpp
src/tf/tf_parser.cpp
+16
-12
test/CMakeLists.txt
test/CMakeLists.txt
+16
-0
No files found.
src/targets/gpu/include/migraphx/gpu/int8_gemm_pack.hpp
View file @
2ba401f0
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
#ifndef MIGRAPHX_GUARD_RTGLIB_INT8_GEMM_PACK_HPP
#ifndef MIGRAPHX_GUARD_RTGLIB_INT8_GEMM_PACK_HPP
#define MIGRAPHX_GUARD_RTGLIB_INT8_GEMM_PACK_HPP
#define MIGRAPHX_GUARD_RTGLIB_INT8_GEMM_PACK_HPP
#include <migraphx/argument.hpp>
#include <migraphx/op/quant_dot.hpp>
#include <migraphx/op/quant_dot.hpp>
#include <migraphx/config.hpp>
#include <migraphx/config.hpp>
#include <utility>
#include <utility>
...
...
src/targets/gpu/include/migraphx/gpu/mlir.hpp
0 → 100644
View file @
2ba401f0
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MIGRAPHX_GUARD_RTGLIB_GPU_MLIR_HPP
#define MIGRAPHX_GUARD_RTGLIB_GPU_MLIR_HPP
#include <string>
#include <vector>
#include <migraphx/config.hpp>
#include <migraphx/gpu/code_object_op.hpp>
#include <migraphx/instruction_ref.hpp>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
struct
module
;
namespace
gpu
{
std
::
string
dump_mlir
(
const
module
&
m
);
code_object_op
compile_mlir
(
const
context
&
ctx
,
const
module
&
m
);
instruction_ref
insert_mlir
(
module
&
m
,
instruction_ref
ins
,
code_object_op
co
,
const
std
::
vector
<
instruction_ref
>&
inputs
);
}
// namespace gpu
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
#endif
src/targets/gpu/include/migraphx/gpu/quant_convolution.hpp
View file @
2ba401f0
...
@@ -41,7 +41,7 @@ struct miopen_quant_convolution
...
@@ -41,7 +41,7 @@ struct miopen_quant_convolution
bool
int8_x4_format
=
false
;
bool
int8_x4_format
=
false
;
shared
<
convolution_descriptor
>
cd
;
shared
<
convolution_descriptor
>
cd
;
miopenConvFwdAlgorithm_t
algo
{};
miopenConvFwdAlgorithm_t
algo
{};
miopenHandle_t
handle
=
nullptr
;
uint64_t
solution_id
=
0
;
template
<
class
Self
,
class
F
>
template
<
class
Self
,
class
F
>
static
auto
reflect
(
Self
&
self
,
F
f
)
static
auto
reflect
(
Self
&
self
,
F
f
)
...
@@ -55,7 +55,7 @@ struct miopen_quant_convolution
...
@@ -55,7 +55,7 @@ struct miopen_quant_convolution
shape
compute_shape
(
const
std
::
vector
<
shape
>&
inputs
)
const
;
shape
compute_shape
(
const
std
::
vector
<
shape
>&
inputs
)
const
;
argument
argument
compute
(
context
&
ctx
,
const
shape
&
output_shape
,
const
std
::
vector
<
argument
>&
args
)
const
;
compute
(
context
&
ctx
,
const
shape
&
output_shape
,
const
std
::
vector
<
argument
>&
args
)
const
;
shape
compile
(
context
&
ctx
,
const
shape
&
output_shape
,
std
::
vector
<
shape
>
inputs
);
shape
find
(
context
&
ctx
,
const
shape
&
output_shape
,
std
::
vector
<
shape
>
inputs
);
void
finalize
(
context
&
ctx
,
const
shape
&
output_shape
,
std
::
vector
<
shape
>
inputs
);
void
finalize
(
context
&
ctx
,
const
shape
&
output_shape
,
std
::
vector
<
shape
>
inputs
);
std
::
ptrdiff_t
output_alias
(
const
std
::
vector
<
shape
>&
shapes
)
const
std
::
ptrdiff_t
output_alias
(
const
std
::
vector
<
shape
>&
shapes
)
const
{
{
...
...
src/targets/gpu/jit/mlir.cpp
0 → 100644
View file @
2ba401f0
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <migraphx/gpu/compiler.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/gpu/context.hpp>
#include <migraphx/gpu/mlir.hpp>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
namespace
gpu
{
struct
mlir_compiler
:
compiler
<
mlir_compiler
>
{
std
::
vector
<
std
::
string
>
names
()
const
{
return
{
"gpu::mlir_conv"
};
}
operation
compile_op
(
context
&
,
const
std
::
vector
<
shape
>&
,
const
value
&
)
const
{
return
{};
}
compiler_replace
compile
(
context
&
ctx
,
instruction_ref
ins
,
const
operation
&
)
const
{
auto
*
smod
=
ins
->
module_inputs
().
front
();
assert
(
smod
->
get_parameter_names
().
size
()
==
ins
->
inputs
().
size
()
-
1
);
return
insert
(
compile_mlir
(
ctx
,
*
smod
));
}
compiler_replace
insert
(
code_object_op
co
)
const
{
return
[
co
=
std
::
move
(
co
)](
module
&
m
,
instruction_ref
ins
)
{
auto
mlir
=
insert_mlir
(
m
,
ins
,
co
,
ins
->
inputs
());
m
.
replace_instruction
(
ins
,
mlir
);
};
}
};
}
// namespace gpu
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
src/targets/gpu/jit/softmax.cpp
0 → 100644
View file @
2ba401f0
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <migraphx/gpu/compiler.hpp>
#include <migraphx/gpu/context.hpp>
#include <migraphx/gpu/compile_hip_code_object.hpp>
#include <migraphx/gpu/compile_hip.hpp>
#include <migraphx/gpu/compile_gen.hpp>
#include <migraphx/cpp_generator.hpp>
#include <migraphx/ranges.hpp>
#include <migraphx/reduce_dims.hpp>
#include <migraphx/stringutils.hpp>
#include <migraphx/dead_code_elimination.hpp>
#include <migraphx/eliminate_common_subexpression.hpp>
#include <migraphx/module.hpp>
#include <migraphx/pass_manager.hpp>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
namespace
gpu
{
using
namespace
migraphx
::
gpu
::
gen
;
// NOLINT
static
const
char
*
const
softmax_kernel
=
R"__migraphx__(
#include <migraphx/kernels/index.hpp>
#include <migraphx/kernels/softmax.hpp>
#include <migraphx/kernels/vectorize.hpp>
#include <args.hpp>
namespace migraphx {
extern "C" {
__global__ void softmax_kernel(void* input_p, void* output_p)
{
transform_args(make_tensors(), ${transformers})(input_p, output_p)([](auto input, auto output) {
softmax<${axis}>(input, output);
});
}
}
} // namespace migraphx
)__migraphx__"
;
struct
softmax_compiler
:
compiler
<
softmax_compiler
>
{
std
::
vector
<
std
::
string
>
names
()
const
{
return
{
"softmax"
};
}
operation
compile_op
(
context
&
ctx
,
const
std
::
vector
<
shape
>&
inputs
,
const
value
&
v
)
const
{
// TODO: Use reduce_dims
auto
axis
=
v
.
at
(
"axis"
).
to
<
int64_t
>
();
auto
faxis
=
find_fast_axis
({
inputs
.
front
()});
vectorize
vec
{};
// Vectorize if the axis is a reduction axis
if
(
faxis
==
axis
)
{
vec
=
vectorize
::
elements
(
faxis
,
inputs
);
}
auto
relements
=
inputs
[
0
].
lens
()[
axis
]
/
vec
.
size
;
auto
nelements
=
(
inputs
.
back
().
elements
()
/
inputs
[
0
].
lens
()[
axis
]);
auto
block_size
=
compute_block_size
(
relements
,
256
);
hip_compile_options
options
;
options
.
set_launch_params
(
v
,
compute_global_for
(
ctx
,
nelements
*
block_size
,
256
),
block_size
);
options
.
output
=
inputs
.
back
();
options
.
inputs
=
inputs
;
options
.
kernel_name
=
"softmax_kernel"
;
auto
src
=
interpolate_string
(
softmax_kernel
,
{{
"transformers"
,
make_transformer_args
(
vec
)},
{
"axis"
,
to_string
(
axis
)}});
return
compile_hip_code_object
(
src
,
options
);
}
compiler_replace
compile
(
context
&
ctx
,
instruction_ref
ins
,
const
operation
&
op
)
const
{
return
replace
(
compile_op
(
ctx
,
to_shapes
(
ins
->
inputs
()),
op
.
to_value
()));
}
};
}
// namespace gpu
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
src/targets/gpu/kernels/include/migraphx/kernels/array.hpp
View file @
2ba401f0
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include <migraphx/kernels/types.hpp>
#include <migraphx/kernels/types.hpp>
#include <migraphx/kernels/type_traits.hpp>
#include <migraphx/kernels/type_traits.hpp>
#include <migraphx/kernels/integral_constant.hpp>
#include <migraphx/kernels/integral_constant.hpp>
#include <migraphx/kernels/functional.hpp>
#include <migraphx/kernels/debug.hpp>
#include <migraphx/kernels/debug.hpp>
namespace
migraphx
{
namespace
migraphx
{
...
@@ -213,6 +214,13 @@ constexpr auto transform(integral_const_array<T, Xs...>, F f)
...
@@ -213,6 +214,13 @@ constexpr auto transform(integral_const_array<T, Xs...>, F f)
return
integral_const_array
<
T
,
f
(
Xs
)...
>
{};
return
integral_const_array
<
T
,
f
(
Xs
)...
>
{};
}
}
template
<
class
T
,
T
...
Xs
,
class
F
>
constexpr
auto
transform_i
(
integral_const_array
<
T
,
Xs
...
>
,
F
f
)
{
return
sequence_c
<
sizeof
...(
Xs
)
>
(
[
=
](
auto
...
is
)
{
return
integral_const_array
<
T
,
f
(
Xs
,
is
)...
>
{};
});
}
template
<
class
T
,
T
...
Xs
,
class
U
,
U
...
Ys
,
class
F
>
template
<
class
T
,
T
...
Xs
,
class
U
,
U
...
Ys
,
class
F
>
constexpr
auto
transform
(
integral_const_array
<
T
,
Xs
...
>
,
integral_const_array
<
U
,
Ys
...
>
,
F
f
)
constexpr
auto
transform
(
integral_const_array
<
T
,
Xs
...
>
,
integral_const_array
<
U
,
Ys
...
>
,
F
f
)
{
{
...
...
src/targets/gpu/kernels/include/migraphx/kernels/functional.hpp
View file @
2ba401f0
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
#ifndef MIGRAPHX_GUARD_KERNELS_FUNCTIONAL_HPP
#ifndef MIGRAPHX_GUARD_KERNELS_FUNCTIONAL_HPP
#define MIGRAPHX_GUARD_KERNELS_FUNCTIONAL_HPP
#define MIGRAPHX_GUARD_KERNELS_FUNCTIONAL_HPP
#include <migraphx/kernels/
array
.hpp>
#include <migraphx/kernels/
integral_constant
.hpp>
// NOLINTNEXTLINE
// NOLINTNEXTLINE
#define MIGRAPHX_RETURNS(...) \
#define MIGRAPHX_RETURNS(...) \
...
...
src/targets/gpu/kernels/include/migraphx/kernels/index.hpp
View file @
2ba401f0
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include <migraphx/kernels/hip.hpp>
#include <migraphx/kernels/hip.hpp>
#include <migraphx/kernels/types.hpp>
#include <migraphx/kernels/types.hpp>
#include <migraphx/kernels/integral_constant.hpp>
#include <migraphx/kernels/integral_constant.hpp>
#include <migraphx/kernels/type_traits.hpp>
namespace
migraphx
{
namespace
migraphx
{
...
@@ -53,29 +54,51 @@ struct index
...
@@ -53,29 +54,51 @@ struct index
return
blockDim
.
x
;
// NOLINT
return
blockDim
.
x
;
// NOLINT
}
}
#endif
#endif
template
<
class
N
,
class
Stride
>
static
constexpr
auto
max_stride_iterations
(
N
n
,
Stride
stride
)
{
return
(
n
-
_c
<
1
>
)
/
stride
+
_c
<
1
>
;
}
template
<
class
F
>
template
<
class
F
,
class
N
,
class
Stride
>
__device__
void
global_stride
(
index_int
n
,
F
f
)
const
static
constexpr
void
for_stride
(
index_int
start
,
N
n
,
Stride
stride
,
F
f
)
{
{
const
auto
stride
=
nglobal
();
if
const
expr
(
not
is_integral
<
N
>
{}
and
not
is_integral
<
Stride
>
{}
and
for
(
in
de
x
_i
nt
i
=
global
;
i
<
n
;
i
+=
stride
)
max_stri
de_i
terations
(
n
,
stride
)
==
1
)
{
{
f
(
i
);
if
constexpr
(
stride
>
n
)
{
if
(
start
<
n
)
f
(
start
);
}
else
{
f
(
start
);
}
}
else
{
for
(
index_int
i
=
start
;
i
<
n
;
i
+=
stride
)
{
f
(
i
);
}
}
}
}
}
template
<
class
F
>
template
<
class
F
,
class
N
>
__device__
void
lo
c
al_stride
(
index_int
n
,
F
f
)
const
__device__
void
g
lo
b
al_stride
(
N
n
,
F
f
)
const
{
{
const
auto
stride
=
nlocal
();
for_stride
(
global
,
n
,
nglobal
(),
f
);
for
(
index_int
i
=
local
;
i
<
n
;
i
+=
stride
)
}
{
f
(
i
);
template
<
class
F
,
class
N
>
}
__device__
void
local_stride
(
N
n
,
F
f
)
const
{
for_stride
(
local
,
n
,
nlocal
(),
f
);
}
}
};
};
inline
__device__
index
make_index
()
inline
__device__
__attribute__
((
const
))
index
make_index
()
{
{
return
index
{
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
,
threadIdx
.
x
,
blockIdx
.
x
};
// NOLINT
return
index
{
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
,
threadIdx
.
x
,
blockIdx
.
x
};
// NOLINT
}
}
...
...
src/targets/gpu/kernels/include/migraphx/kernels/preload.hpp
View file @
2ba401f0
...
@@ -186,7 +186,8 @@ __device__ auto auto_preload(index idx)
...
@@ -186,7 +186,8 @@ __device__ auto auto_preload(index idx)
{
{
return
make_transform
([
=
](
auto
f
,
auto
...
xs
)
{
return
make_transform
([
=
](
auto
f
,
auto
...
xs
)
{
auto
invoke
=
[
=
](
auto
...
ys
)
{
auto
invoke
=
[
=
](
auto
...
ys
)
{
__syncthreads
();
if
constexpr
((
Bs
or
...))
__syncthreads
();
f
(
ys
...);
f
(
ys
...);
};
};
join
(
invoke
,
preload_copy
<
Bs
>
(
idx
,
xs
)...);
join
(
invoke
,
preload_copy
<
Bs
>
(
idx
,
xs
)...);
...
...
src/targets/gpu/kernels/include/migraphx/kernels/reduce.hpp
View file @
2ba401f0
...
@@ -175,6 +175,21 @@ constexpr auto sliced(Slicer slicer, F f)
...
@@ -175,6 +175,21 @@ constexpr auto sliced(Slicer slicer, F f)
};
};
}
}
template
<
class
Input
,
index_int
Axis
>
constexpr
auto
compute_reduce_axis
()
{
constexpr
auto
lens
=
transform_i
(
get_shape_c
<
Input
>
{}.
lens
,
[](
index_int
x
,
index_int
i
)
->
index_int
{
if
(
i
==
Axis
)
return
1
;
return
x
;
});
return
make_shape
(
lens
,
get_shape_c
<
Input
>
{}.
strides
);
}
template
<
class
Input
,
index_int
Axis
>
using
with_axis
=
decltype
(
compute_reduce_axis
<
Input
,
Axis
>
());
struct
block
struct
block
{
{
template
<
class
Slicer
>
template
<
class
Slicer
>
...
@@ -201,6 +216,14 @@ struct block
...
@@ -201,6 +216,14 @@ struct block
if
(
idx
.
local
==
0
)
if
(
idx
.
local
==
0
)
f
();
f
();
}
}
template
<
class
F
>
__device__
auto
inner
(
F
f
)
const
{
return
sliced
(
slicer
,
[
=
](
auto
x
,
auto
...
xs
)
{
idx
.
local_stride
(
x
.
get_shape
().
elements
(),
[
&
](
auto
j
)
{
f
(
x
[
j
],
xs
[
j
]...);
});
});
}
};
};
template
<
class
Slicer
>
template
<
class
Slicer
>
...
@@ -247,6 +270,17 @@ struct lane
...
@@ -247,6 +270,17 @@ struct lane
{
{
f
();
f
();
}
}
template
<
class
F
>
__device__
auto
inner
(
F
f
)
const
{
return
sliced
(
slicer
,
[
=
](
auto
x
,
auto
...
xs
)
{
for
(
index_int
j
=
0
;
j
<
x
.
get_shape
().
elements
();
j
++
)
{
f
(
x
[
j
],
xs
[
j
]...);
}
});
}
};
};
template
<
class
Slicer
>
template
<
class
Slicer
>
...
...
src/targets/gpu/kernels/include/migraphx/kernels/shape.hpp
View file @
2ba401f0
...
@@ -32,6 +32,7 @@ namespace migraphx {
...
@@ -32,6 +32,7 @@ namespace migraphx {
template
<
class
Lens
,
class
Strides
>
template
<
class
Lens
,
class
Strides
>
struct
shape
struct
shape
{
{
using
shape_type
=
shape
;
using
index_array
=
typename
Lens
::
base_array
;
using
index_array
=
typename
Lens
::
base_array
;
Lens
lens
=
{};
Lens
lens
=
{};
Strides
strides
=
{};
Strides
strides
=
{};
...
...
src/targets/gpu/kernels/include/migraphx/kernels/softmax.hpp
0 → 100644
View file @
2ba401f0
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MIGRAPHX_GUARD_KERNELS_SOFTMAX_HPP
#define MIGRAPHX_GUARD_KERNELS_SOFTMAX_HPP
#include <migraphx/kernels/reduce.hpp>
#include <migraphx/kernels/ops.hpp>
namespace
migraphx
{
template
<
index_int
Axis
,
class
Input
,
class
Output
>
__device__
void
softmax
(
Input
input
,
Output
output
)
{
reduce
::
block
::
run
<
reduce
::
with_axis
<
Input
,
Axis
>>
([
&
](
auto
,
auto
r
)
{
auto
batch_max
=
r
.
reduce
(
op
::
max
{},
lowest
{},
op
::
id
{})(
input
);
auto
batch_sum
=
r
.
reduce
(
op
::
sum
{},
0
,
[
&
](
auto
x
)
{
return
migraphx
::
exp
(
x
-
batch_max
);
})(
input
);
r
.
inner
([
&
](
auto
&
y
,
auto
x
)
{
y
=
migraphx
::
exp
(
x
-
batch_max
)
/
batch_sum
;
})(
output
,
input
);
});
}
}
// namespace migraphx
#endif // MIGRAPHX_GUARD_KERNELS_SOFTMAX_HPP
src/targets/gpu/kernels/include/migraphx/kernels/vec.hpp
View file @
2ba401f0
...
@@ -27,6 +27,8 @@
...
@@ -27,6 +27,8 @@
#include <migraphx/kernels/types.hpp>
#include <migraphx/kernels/types.hpp>
#include <migraphx/kernels/integral_constant.hpp>
#include <migraphx/kernels/integral_constant.hpp>
#include <migraphx/kernels/functional.hpp>
#include <migraphx/kernels/functional.hpp>
#include <migraphx/kernels/type_traits.hpp>
#include <migraphx/kernels/debug.hpp>
namespace
migraphx
{
namespace
migraphx
{
...
...
src/targets/gpu/lowering.cpp
View file @
2ba401f0
...
@@ -186,7 +186,6 @@ struct miopen_apply
...
@@ -186,7 +186,6 @@ struct miopen_apply
add_extend_op
(
"rnn_var_sl_shift_output"
);
add_extend_op
(
"rnn_var_sl_shift_output"
);
add_extend_op
(
"rnn_var_sl_shift_sequence"
);
add_extend_op
(
"rnn_var_sl_shift_sequence"
);
add_extend_op
(
"scatter_none"
);
add_extend_op
(
"scatter_none"
);
add_extend_op
(
"softmax"
);
add_extend_op
(
"topk"
);
add_extend_op
(
"topk"
);
add_batch_norm_inference_op
();
add_batch_norm_inference_op
();
...
@@ -301,7 +300,7 @@ struct miopen_apply
...
@@ -301,7 +300,7 @@ struct miopen_apply
auto
&&
op
=
any_cast
<
op
::
deconvolution
>
(
ins
->
get_operator
());
auto
&&
op
=
any_cast
<
op
::
deconvolution
>
(
ins
->
get_operator
());
auto
conv
=
miopen_deconvolution
{
op
,
make_deconv
(
op
)};
auto
conv
=
miopen_deconvolution
{
op
,
make_deconv
(
op
)};
auto
ws
=
conv
.
compile
(
get_context
(),
ins
->
get_shape
(),
to_shapes
(
ins
->
inputs
()));
auto
ws
=
conv
.
find
(
get_context
(),
ins
->
get_shape
(),
to_shapes
(
ins
->
inputs
()));
auto
workspace
=
insert_allocation
(
ins
,
ws
);
auto
workspace
=
insert_allocation
(
ins
,
ws
);
auto
output
=
insert_allocation
(
ins
,
ins
->
get_shape
());
auto
output
=
insert_allocation
(
ins
,
ins
->
get_shape
());
...
@@ -332,7 +331,7 @@ struct miopen_apply
...
@@ -332,7 +331,7 @@ struct miopen_apply
miopen_quant_convolution
conv
;
miopen_quant_convolution
conv
;
auto
compile_quant_conv_with_format
=
[
&
](
bool
format
)
{
auto
compile_quant_conv_with_format
=
[
&
](
bool
format
)
{
conv
=
miopen_quant_convolution
{
op
,
format
,
make_conv
(
op
)};
conv
=
miopen_quant_convolution
{
op
,
format
,
make_conv
(
op
)};
ws
=
conv
.
compile
(
get_context
(),
ins
->
get_shape
(),
to_shapes
(
ins
->
inputs
()));
ws
=
conv
.
find
(
get_context
(),
ins
->
get_shape
(),
to_shapes
(
ins
->
inputs
()));
};
};
try
try
...
...
src/targets/gpu/mlir.cpp
0 → 100644
View file @
2ba401f0
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <migraphx/gpu/mlir.hpp>
#ifdef MIGRAPHX_MLIR
#include <mlir-c/IR.h>
#include <mlir-c/BuiltinAttributes.h>
#include <mlir-c/BuiltinTypes.h>
#include <mlir-c/Diagnostics.h>
#include <mlir-c/Dialect/MIGraphX.h>
#include <mlir-c/IntegerSet.h>
#include <mlir-c/Pass.h>
#include <mlir-c/Registration.h>
#endif
#include <migraphx/env.hpp>
#include <migraphx/manage_ptr.hpp>
#include <migraphx/module.hpp>
#include <migraphx/instruction.hpp>
#include <migraphx/config.hpp>
#include <migraphx/ranges.hpp>
#include <migraphx/gpu/code_object_op.hpp>
#include <migraphx/gpu/context.hpp>
#include <migraphx/gpu/device_name.hpp>
#include <migraphx/iterator_for.hpp>
#include <deque>
#include <variant>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
namespace
gpu
{
MIGRAPHX_DECLARE_ENV_VAR
(
MIGRAPHX_TRACE_MLIR
);
#ifdef MIGRAPHX_MLIR
template
<
class
T
,
class
F
,
F
f
>
// NOLINT
struct
mlir_handle
{
struct
ptr
{
ptr
()
=
default
;
ptr
(
std
::
nullptr_t
)
{}
ptr
(
T
x
)
:
obj
(
x
)
{}
std
::
intptr_t
get_value
()
const
{
static_assert
(
sizeof
(
T
)
==
sizeof
(
std
::
intptr_t
),
"MLIR Handle different size"
);
return
reinterpret_cast
<
const
std
::
intptr_t
&>
(
obj
);
}
T
get
()
const
{
return
obj
;
}
friend
bool
operator
==
(
ptr
x
,
ptr
y
)
{
return
x
.
get_value
()
==
y
.
get_value
();
}
friend
bool
operator
!=
(
ptr
x
,
ptr
y
)
{
return
!
(
x
==
y
);
}
T
obj
{};
};
struct
deleter
{
using
pointer
=
ptr
;
void
operator
()(
pointer
x
)
const
{
if
(
x
!=
nullptr
)
{
(
void
)
f
(
x
.
obj
);
}
}
};
mlir_handle
()
:
handle
(
nullptr
)
{}
mlir_handle
(
T
p
)
:
handle
(
ptr
{
p
})
{}
T
get
()
const
{
return
handle
.
get
().
get
();
}
T
release
()
{
return
handle
.
release
().
get
();
}
private:
std
::
unique_ptr
<
ptr
,
deleter
>
handle
;
};
#define MIGRAPHX_MANAGE_MLIR_HANDLE(T, F) migraphx::gpu::mlir_handle<T, decltype(&F), &F> // NOLINT
using
mlir_context
=
MIGRAPHX_MANAGE_MLIR_HANDLE
(
MlirContext
,
mlirContextDestroy
);
using
mlir_module
=
MIGRAPHX_MANAGE_MLIR_HANDLE
(
MlirModule
,
mlirModuleDestroy
);
using
mlir_operation
=
MIGRAPHX_MANAGE_MLIR_HANDLE
(
MlirOperation
,
mlirOperationDestroy
);
using
mlir_op_printing_flags
=
MIGRAPHX_MANAGE_MLIR_HANDLE
(
MlirOpPrintingFlags
,
mlirOpPrintingFlagsDestroy
);
using
mlir_region
=
MIGRAPHX_MANAGE_MLIR_HANDLE
(
MlirRegion
,
mlirRegionDestroy
);
using
mlir_block
=
MIGRAPHX_MANAGE_MLIR_HANDLE
(
MlirBlock
,
mlirBlockDestroy
);
using
mlir_pass_manager
=
MIGRAPHX_MANAGE_MLIR_HANDLE
(
MlirPassManager
,
mlirPassManagerDestroy
);
std
::
string_view
to_string_view
(
MlirStringRef
s
)
{
return
{
s
.
data
,
s
.
length
};
}
MlirStringRef
make_mlir_string_ref
(
const
std
::
string_view
&
s
)
{
return
mlirStringRefCreate
(
s
.
data
(),
s
.
size
());
}
template
<
class
F
,
class
T
,
class
Printer
>
void
mlir_print
(
F
f
,
T
x
,
Printer
printer
)
{
f
(
x
,
+
[](
MlirStringRef
s
,
void
*
data
)
{
(
*
reinterpret_cast
<
Printer
*>
(
data
))(
to_string_view
(
s
));
},
&
printer
);
}
template
<
class
F
,
class
T
>
void
mlir_print
(
F
f
,
T
x
,
std
::
ostream
&
os
)
{
mlir_print
(
f
,
x
,
[
&
](
auto
s
)
{
os
<<
s
;
});
}
template
<
class
F
,
class
T
>
std
::
string
mlir_print
(
F
f
,
T
x
)
{
std
::
stringstream
ss
;
mlir_print
(
f
,
x
,
[
&
](
auto
s
)
{
ss
<<
s
;
});
return
ss
.
str
();
}
struct
mlir_program
{
mlir_program
()
:
ctx
(
mlirContextCreate
()),
location
(
mlirLocationUnknownGet
(
ctx
.
get
())),
mmodule
(
mlirModuleCreateEmpty
(
location
))
{
MlirDialectHandle
mixr_handle
=
mlirGetDialectHandle__migraphx__
();
mlirDialectHandleRegisterDialect
(
mixr_handle
,
ctx
.
get
());
mlirRegisterAllDialects
(
ctx
.
get
());
mlirContextSetAllowUnregisteredDialects
(
ctx
.
get
(),
true
/*allow*/
);
}
MlirType
make_type
(
shape
::
type_t
t
)
const
{
MlirType
result
;
shape
::
visit
(
t
,
[
&
](
auto
as
)
{
if
(
as
.
type_enum
()
==
shape
::
float_type
)
result
=
mlirF32TypeGet
(
ctx
.
get
());
else
if
(
as
.
type_enum
()
==
shape
::
half_type
)
result
=
mlirF16TypeGet
(
ctx
.
get
());
else
if
(
as
.
type_enum
()
==
shape
::
double_type
)
result
=
mlirF64TypeGet
(
ctx
.
get
());
else
if
(
as
.
is_integral
())
{
if
(
as
.
is_signed
())
result
=
mlirIntegerTypeSignedGet
(
ctx
.
get
(),
as
.
size
()
*
8
);
else
result
=
mlirIntegerTypeGet
(
ctx
.
get
(),
as
.
size
()
*
8
);
}
else
MIGRAPHX_THROW
(
"Unsupported type: "
+
std
::
to_string
(
as
.
type_enum
()));
});
return
result
;
}
MlirType
make_tensor
(
const
shape
&
s
)
const
{
assert
(
s
.
standard
());
std
::
vector
<
int64_t
>
lens
(
s
.
lens
().
begin
(),
s
.
lens
().
end
());
return
mlirRankedTensorTypeGet
(
lens
.
size
(),
lens
.
data
(),
make_type
(
s
.
type
()),
mlirAttributeGetNull
());
}
template
<
class
Range
>
std
::
vector
<
MlirType
>
make_tensors
(
const
Range
&
r
)
{
std
::
vector
<
MlirType
>
result
;
std
::
transform
(
r
.
begin
(),
r
.
end
(),
std
::
back_inserter
(
result
),
[
&
](
const
auto
&
s
)
{
return
make_tensor
(
s
);
});
return
result
;
}
MlirType
make_function_type
(
const
std
::
vector
<
shape
>&
inputs
,
const
std
::
vector
<
shape
>&
outputs
)
{
auto
in
=
make_tensors
(
inputs
);
auto
out
=
make_tensors
(
outputs
);
return
mlirFunctionTypeGet
(
ctx
.
get
(),
in
.
size
(),
in
.
data
(),
out
.
size
(),
out
.
data
());
}
MlirIdentifier
id
(
const
std
::
string_view
&
s
)
const
{
return
mlirIdentifierGet
(
ctx
.
get
(),
make_mlir_string_ref
(
s
));
}
MlirAttribute
attribute
(
std
::
int64_t
i
)
const
{
if
(
i
<
0
)
MIGRAPHX_THROW
(
"MLIR cant handle negative values since they are ambiguous"
);
return
mlirIntegerAttrGet
(
mlirIntegerTypeGet
(
ctx
.
get
(),
64
),
i
);
}
MlirAttribute
attribute
(
std
::
uint64_t
i
)
const
{
if
(
i
>
(
std
::
numeric_limits
<
std
::
uint64_t
>::
max
()
/
2
))
MIGRAPHX_THROW
(
"MLIR cant handle large integer values since they are ambiguous"
);
return
mlirIntegerAttrGet
(
mlirIntegerTypeGet
(
ctx
.
get
(),
64
),
i
);
}
MlirAttribute
attribute
(
unsigned
char
i
)
const
{
return
attribute
(
std
::
uint64_t
(
i
));
}
MlirAttribute
attribute
(
bool
b
)
const
{
return
mlirBoolAttrGet
(
ctx
.
get
(),
b
?
1
:
0
);
}
MlirAttribute
attribute
(
double
d
)
const
{
return
mlirFloatAttrDoubleGet
(
ctx
.
get
(),
mlirF64TypeGet
(
ctx
.
get
()),
d
);
}
MlirAttribute
attribute
(
const
std
::
string
&
s
)
const
{
return
mlirStringAttrGet
(
ctx
.
get
(),
make_mlir_string_ref
(
s
));
}
MlirAttribute
attribute
(
std
::
nullptr_t
)
const
{
return
{};
}
template
<
class
T
>
MlirAttribute
attribute
(
const
std
::
vector
<
T
>&
v
)
const
{
std
::
vector
<
MlirAttribute
>
attributes
;
attributes
.
reserve
(
v
.
size
());
std
::
transform
(
v
.
begin
(),
v
.
end
(),
std
::
back_inserter
(
attributes
),
[
&
](
auto
&&
x
)
{
return
attribute
(
x
);
});
return
mlirArrayAttrGet
(
ctx
.
get
(),
attributes
.
size
(),
attributes
.
data
());
}
MlirAttribute
attribute
(
const
value
&
v
)
const
{
MlirAttribute
attr
;
v
.
visit_value
([
&
](
auto
&&
x
)
{
attr
=
attribute
(
x
);
});
return
attr
;
}
MlirAttribute
attribute
(
const
std
::
vector
<
value
>&
v
)
const
{
if
(
v
.
empty
())
{
return
mlirArrayAttrGet
(
ctx
.
get
(),
0
,
nullptr
);
}
if
(
not
v
.
front
().
get_key
().
empty
())
{
std
::
vector
<
MlirNamedAttribute
>
attributes
=
name_attributes
(
v
);
return
mlirDictionaryAttrGet
(
ctx
.
get
(),
attributes
.
size
(),
attributes
.
data
());
}
else
{
std
::
vector
<
MlirAttribute
>
attributes
;
attributes
.
reserve
(
v
.
size
());
std
::
transform
(
v
.
begin
(),
v
.
end
(),
std
::
back_inserter
(
attributes
),
[
&
](
auto
&&
x
)
{
return
attribute
(
x
);
});
return
mlirArrayAttrGet
(
ctx
.
get
(),
attributes
.
size
(),
attributes
.
data
());
}
}
MlirAttribute
attribute
(
MlirType
t
)
const
{
return
mlirTypeAttrGet
(
t
);
}
MlirAttribute
attribute
(
MlirAttribute
a
)
const
{
return
a
;
}
template
<
class
T
>
MlirNamedAttribute
name_attribute
(
const
std
::
string_view
&
key
,
const
T
&
x
)
const
{
MlirNamedAttribute
attr
;
attr
.
name
=
id
(
key
);
attr
.
attribute
=
attribute
(
x
);
return
attr
;
}
using
attribute_t
=
std
::
variant
<
std
::
nullptr_t
,
std
::
uint64_t
,
unsigned
char
,
bool
,
double
,
std
::
string
,
value
,
std
::
vector
<
value
>
,
MlirType
>
;
using
named_attribute_t
=
std
::
pair
<
std
::
string_view
,
attribute_t
>
;
MlirNamedAttribute
name_attribute
(
const
named_attribute_t
&
na
)
const
{
return
name_attribute
(
na
.
first
,
std
::
visit
([
&
](
const
auto
&
x
)
{
return
attribute
(
x
);
},
na
.
second
));
}
std
::
vector
<
MlirNamedAttribute
>
name_attributes
(
const
std
::
vector
<
named_attribute_t
>&
named_attrs
)
const
{
std
::
vector
<
MlirNamedAttribute
>
attributes
;
attributes
.
reserve
(
named_attrs
.
size
());
std
::
transform
(
named_attrs
.
begin
(),
named_attrs
.
end
(),
std
::
back_inserter
(
attributes
),
[
&
](
const
named_attribute_t
&
a
)
{
return
name_attribute
(
a
);
});
return
attributes
;
}
std
::
vector
<
MlirNamedAttribute
>
name_attributes
(
const
value
&
v
)
const
{
std
::
vector
<
MlirNamedAttribute
>
attributes
;
attributes
.
reserve
(
v
.
size
());
std
::
transform
(
v
.
begin
(),
v
.
end
(),
std
::
back_inserter
(
attributes
),
[
&
](
const
value
&
x
)
{
return
name_attribute
(
x
.
get_key
(),
x
.
without_key
());
});
return
attributes
;
}
struct
mlir_operation_state
{
mlir_operation_state
(
mlir_program
&
p
,
const
std
::
string_view
&
name
)
:
prog
(
&
p
),
op_state
(
mlirOperationStateGet
(
make_mlir_string_ref
(
name
),
p
.
location
))
{
}
mlir_operation_state
&
add_attributes
(
const
std
::
vector
<
named_attribute_t
>&
named_attrs
)
{
auto
attributes
=
prog
->
name_attributes
(
named_attrs
);
mlirOperationStateAddAttributes
(
&
op_state
,
attributes
.
size
(),
attributes
.
data
());
return
*
this
;
}
mlir_operation_state
&
add_attribute_value
(
const
value
&
v
)
{
auto
attributes
=
prog
->
name_attributes
(
v
);
mlirOperationStateAddAttributes
(
&
op_state
,
attributes
.
size
(),
attributes
.
data
());
return
*
this
;
}
mlir_operation_state
&
add_regions
(
std
::
vector
<
mlir_region
>
rs
)
{
regions
=
std
::
move
(
rs
);
return
*
this
;
}
mlir_operation_state
&
add_region
(
mlir_region
r
)
{
regions
.
emplace_back
(
std
::
move
(
r
));
return
*
this
;
}
mlir_operation_state
&
add_results
(
const
std
::
vector
<
shape
>&
outputs
)
{
auto
x
=
prog
->
make_tensors
(
outputs
);
mlirOperationStateAddResults
(
&
op_state
,
x
.
size
(),
x
.
data
());
return
*
this
;
}
mlir_operation_state
&
add_operands
(
const
std
::
vector
<
MlirValue
>&
inputs
)
{
mlirOperationStateAddOperands
(
&
op_state
,
inputs
.
size
(),
inputs
.
data
());
return
*
this
;
}
mlir_operation
create_operation
()
{
std
::
vector
<
MlirRegion
>
mregions
(
regions
.
size
());
std
::
transform
(
regions
.
begin
(),
regions
.
end
(),
mregions
.
begin
(),
[](
const
auto
&
r
)
{
return
r
.
get
();
});
mlirOperationStateAddOwnedRegions
(
&
op_state
,
mregions
.
size
(),
mregions
.
data
());
mlir_operation
op
(
mlirOperationCreate
(
&
op_state
));
// Release memory since mlir_operation owns it
for
(
auto
&
r
:
regions
)
r
.
release
();
regions
.
clear
();
return
op
;
}
mlir_program
*
prog
;
MlirOperationState
op_state
;
std
::
vector
<
mlir_region
>
regions
=
{};
};
mlir_operation_state
create_operation_state
(
const
std
::
string_view
&
name
)
{
return
{
*
this
,
name
};
}
std
::
vector
<
MlirValue
>
insert
(
MlirBlock
body
,
mlir_operation_state
ops
)
{
std
::
vector
<
MlirValue
>
result
;
mlir_operation
op
=
ops
.
create_operation
();
auto
weak_op
=
op
.
get
();
mlirBlockAppendOwnedOperation
(
body
,
op
.
release
());
auto
n
=
mlirOperationGetNumResults
(
weak_op
);
result
.
reserve
(
n
);
transform
(
range
(
n
),
std
::
back_inserter
(
result
),
[
&
](
auto
i
)
{
return
mlirOperationGetResult
(
weak_op
,
i
);
});
return
result
;
}
MlirBlock
insert
(
MlirBlock
body
,
const
module
&
m
,
std
::
unordered_map
<
instruction_ref
,
MlirValue
>&
ins_map
)
{
auto
names
=
m
.
get_parameter_names
();
std
::
sort
(
names
.
begin
(),
names
.
end
());
std
::
vector
<
shape
>
inputs
;
std
::
transform
(
names
.
begin
(),
names
.
end
(),
std
::
back_inserter
(
inputs
),
[
&
](
const
std
::
string
&
name
)
{
return
m
.
get_parameter_shape
(
name
);
});
std
::
vector
<
shape
>
outputs
=
m
.
get_output_shapes
();
std
::
vector
<
MlirLocation
>
arg_locs
(
inputs
.
size
(),
location
);
auto
body_inputs
=
make_tensors
(
inputs
);
mlir_region
region
=
mlirRegionCreate
();
mlir_block
fbody
=
mlirBlockCreate
(
body_inputs
.
size
(),
body_inputs
.
data
(),
arg_locs
.
data
());
MlirBlock
result
=
fbody
.
get
();
mlirRegionAppendOwnedBlock
(
region
.
get
(),
fbody
.
release
());
auto
ops
=
create_operation_state
(
"func.func"
);
ops
.
add_attributes
({{
"function_type"
,
make_function_type
(
inputs
,
outputs
)},
{
"sym_name"
,
std
::
string
(
"main"
)},
{
"kernel"
,
std
::
string
(
"mixr"
)}});
ops
.
add_region
(
std
::
move
(
region
));
insert
(
body
,
std
::
move
(
ops
));
for
(
auto
i
:
range
(
names
.
size
()))
ins_map
[
m
.
get_parameter
(
names
[
i
])]
=
mlirBlockGetArgument
(
result
,
i
);
return
result
;
}
static
std
::
string
get_name
(
instruction_ref
ins
)
{
if
(
ins
->
name
()
==
"@return"
)
return
"func.return"
;
return
"migraphx."
+
ins
->
name
();
}
static
value
get_operator_value
(
const
operation
&
op
)
{
auto
v
=
op
.
to_value
();
if
(
op
.
name
()
==
"convolution"
)
{
// Adjust symetrical padding
if
(
v
.
at
(
"padding"
).
size
()
==
v
.
at
(
"stride"
).
size
())
{
auto
padding
=
v
.
at
(
"padding"
);
std
::
copy
(
padding
.
begin
(),
padding
.
end
(),
std
::
back_inserter
(
v
.
at
(
"padding"
)));
}
}
return
v
;
}
static
shape
get_shape
(
instruction_ref
ins
)
{
if
(
ins
->
name
()
==
"@return"
)
{
assert
(
ins
->
inputs
().
size
()
==
1
);
return
ins
->
inputs
().
front
()
->
get_shape
();
}
return
ins
->
get_shape
();
}
void
parse
(
const
module
&
m
)
{
auto
mbody
=
mlirModuleGetBody
(
mmodule
.
get
());
std
::
unordered_map
<
instruction_ref
,
MlirValue
>
ins_map
;
auto
fbody
=
insert
(
mbody
,
m
,
ins_map
);
for
(
auto
ins
:
iterator_for
(
m
))
{
if
(
ins
->
name
()
==
"@param"
)
continue
;
auto
name
=
get_name
(
ins
);
auto
ops
=
create_operation_state
(
name
);
ops
.
add_attribute_value
(
get_operator_value
(
ins
->
get_operator
()));
if
(
ins
->
name
()
!=
"@return"
)
ops
.
add_results
({
get_shape
(
ins
)});
std
::
vector
<
MlirValue
>
inputs
;
transform
(
ins
->
inputs
(),
std
::
back_inserter
(
inputs
),
[
&
](
auto
i
)
{
return
ins_map
.
at
(
i
);
});
ops
.
add_operands
(
inputs
);
auto
outputs
=
insert
(
fbody
,
std
::
move
(
ops
));
if
(
ins
->
name
()
!=
"@return"
)
{
assert
(
outputs
.
size
()
==
1
);
ins_map
[
ins
]
=
outputs
.
front
();
}
}
}
code_object_op
compile
()
MIGRAPHX_TIDY_CONST
{
mlir_pass_manager
pm
{
mlirPassManagerCreate
(
ctx
.
get
())};
// 1st pipeline to call
mlirMIGraphXAddHighLevelPipeline
(
pm
.
get
());
// 2nd pipeline to call
std
::
string
tname
=
get_device_name
();
// HACK: Since MLIR can't handle the full target name
auto
hacked_tname
=
tname
.
substr
(
0
,
tname
.
find
(
':'
));
if
(
tname
.
size
()
!=
hacked_tname
.
size
())
std
::
cout
<<
"*************** WARNING: MLIR may not compile the correct target features for: "
<<
tname
<<
std
::
endl
;
mlirMIGraphXAddBackendPipeline
(
pm
.
get
(),
hacked_tname
.
c_str
(),
"amdgcn-amd-amdhsa"
,
""
);
mlirPassManagerRun
(
pm
.
get
(),
mmodule
.
get
());
code_object_op
op
{};
op
.
symbol_name
=
"main"
;
op
.
code_object
=
get_binary
();
std
::
tie
(
op
.
global
,
op
.
local
)
=
get_launch_params
();
return
op
;
}
std
::
pair
<
std
::
size_t
,
std
::
size_t
>
get_launch_params
()
const
{
uint32_t
attrs
[
2
];
// returns block and grid sizes
mlirGetKernelAttrs
(
mmodule
.
get
(),
attrs
);
std
::
size_t
local
=
attrs
[
0
];
std
::
size_t
global
=
local
*
attrs
[
1
];
return
{
global
,
local
};
}
value
::
binary
get_binary
()
const
{
int
size
=
0
;
mlirGetBinary
(
mmodule
.
get
(),
&
size
,
nullptr
);
value
::
binary
result
(
size
);
if
(
mlirGetBinary
(
mmodule
.
get
(),
&
size
,
reinterpret_cast
<
char
*>
(
result
.
data
())))
return
result
;
MIGRAPHX_THROW
(
"Failed to compile mlir program"
);
}
mlir_context
ctx
;
MlirLocation
location
;
mlir_module
mmodule
;
std
::
deque
<
std
::
string
>
strings
{};
};
std
::
string
dump_mlir
(
const
module
&
m
)
{
mlir_program
mp
;
mp
.
parse
(
m
);
auto
mod_op
=
mlirModuleGetOperation
(
mp
.
mmodule
.
get
());
return
mlir_print
(
&
mlirOperationPrint
,
mod_op
);
}
code_object_op
compile_mlir
(
const
context
&
,
const
module
&
m
)
{
const
bool
trace
=
enabled
(
MIGRAPHX_TRACE_MLIR
{});
if
(
trace
)
std
::
cout
<<
m
<<
std
::
endl
;
mlir_program
mp
;
mp
.
parse
(
m
);
auto
mod_op
=
mlirModuleGetOperation
(
mp
.
mmodule
.
get
());
if
(
trace
)
std
::
cout
<<
mlir_print
(
&
mlirOperationPrint
,
mod_op
)
<<
std
::
endl
;
auto
co
=
mp
.
compile
();
co
.
output
=
m
.
get_output_shapes
().
front
();
return
co
;
}
instruction_ref
insert_mlir
(
module
&
m
,
instruction_ref
ins
,
code_object_op
co
,
const
std
::
vector
<
instruction_ref
>&
inputs
)
{
std
::
vector
<
instruction_ref
>
refs
;
refs
.
reserve
(
inputs
.
size
()
*
15
);
std
::
unordered_map
<
uint64_t
,
instruction_ref
>
literal_map
{};
auto
get_literal
=
[
&
](
uint64_t
value
)
{
auto
fi
=
literal_map
.
find
(
value
);
if
(
fi
!=
literal_map
.
end
())
return
fi
->
second
;
auto
lit
=
m
.
add_literal
(
value
);
literal_map
.
emplace
(
value
,
lit
);
return
lit
;
};
std
::
size_t
last
=
0
;
for
(
auto
input
:
inputs
)
{
const
size_t
offset
=
0
;
auto
s
=
input
->
get_shape
();
last
=
refs
.
size
();
refs
.
push_back
(
input
);
refs
.
push_back
(
input
);
refs
.
push_back
(
get_literal
(
offset
));
// offset
// dim sizes
std
::
transform
(
s
.
lens
().
begin
(),
s
.
lens
().
end
(),
std
::
back_inserter
(
refs
),
[
&
](
const
auto
&
lval
)
{
return
get_literal
(
lval
);
});
// refs.push_back(get_literal(1)); // G
// dim strides
std
::
transform
(
s
.
strides
().
begin
(),
s
.
strides
().
end
(),
std
::
back_inserter
(
refs
),
[
&
](
const
auto
&
lval
)
{
return
get_literal
(
lval
);
});
// refs.push_back(get_literal(1)); // G
}
co
.
expected_inputs
=
to_shapes
(
refs
);
co
.
output_arg
=
last
;
return
m
.
insert_instruction
(
ins
,
co
,
refs
);
}
#else
std
::
string
dump_mlir
(
const
module
&
)
{
return
{};
}
code_object_op
compile_mlir
(
const
context
&
,
const
module
&
)
{
return
{};
}
template
<
class
T
>
void
use
(
T
&
)
{
}
instruction_ref
// cppcheck-suppress funcArgNamesDifferent
insert_mlir
(
module
&
m
,
instruction_ref
,
code_object_op
co
,
const
std
::
vector
<
instruction_ref
>&
)
{
use
(
co
);
return
m
.
end
();
}
#endif
}
// namespace gpu
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
src/targets/gpu/mlir_conv.cpp
deleted
100644 → 0
View file @
a330d428
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <migraphx/gpu/mlir_conv.hpp>
#include <migraphx/manage_ptr.hpp>
#include <migraphx/instruction.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/op/convolution.hpp>
#include <migraphx/gpu/context.hpp>
#include <migraphx/gpu/convolution.hpp>
#include <migraphx/iterator_for.hpp>
#include <migraphx/program.hpp>
#include <migraphx/ranges.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/program.hpp>
#include <migraphx/gpu/kernel.hpp>
#include <migraphx/gpu/target.hpp>
#include <migraphx/gpu/hip.hpp>
#include <migraphx/gpu/compile_hip.hpp>
#include <utility>
#include <functional>
#include <algorithm>
#ifdef MIGRAPHX_MLIR_MIOPEN_SUPPORT
#include <Miir.h>
#endif // MIGRAPHX_MLIR_MIOPEN_SUPPORT
#include <cstdio>
namespace
migraphx
{
inline
namespace
MIGRAPHX_INLINE_NS
{
namespace
gpu
{
struct
mlir_apply
{
module
*
mod
=
nullptr
;
const
mlir_conv
*
pass
=
nullptr
;
const
char
*
mlir_kernel_name
=
"migraphx_conv2d"
;
std
::
unordered_map
<
uint64_t
,
instruction_ref
>
literal_map
{};
struct
execution_spec
{
migraphx
::
value
::
binary
binary
;
size_t
global_size
;
size_t
local_size
;
execution_spec
(
migraphx
::
value
::
binary
&&
binary_m
,
size_t
global_s
,
size_t
local_s
)
:
binary
(
std
::
move
(
binary_m
)),
global_size
(
global_s
),
local_size
(
local_s
)
{
}
};
std
::
unordered_map
<
std
::
string
,
std
::
shared_ptr
<
execution_spec
>>
binary_map
{};
context
&
get_context
()
const
{
assert
(
pass
!=
nullptr
);
assert
(
pass
->
ctx
!=
nullptr
);
return
*
pass
->
ctx
;
}
void
init
()
const
{
assert
(
mod
!=
nullptr
);
assert
(
pass
!=
nullptr
);
}
std
::
shared_ptr
<
execution_spec
>
make_mlir_binary
(
instruction_ref
op_r
)
{
std
::
shared_ptr
<
execution_spec
>
result
;
#ifdef MIGRAPHX_MLIR_MIOPEN_SUPPORT
auto
conv
=
any_cast
<
op
::
convolution
>
(
op_r
->
get_operator
());
auto
inp_t
=
op_r
->
inputs
().
at
(
0
)
->
get_shape
();
auto
flt_t
=
op_r
->
inputs
().
at
(
1
)
->
get_shape
();
auto
out_t
=
op_r
->
get_shape
();
auto
get_type_str
=
[](
const
shape
&
s
)
->
const
char
*
{
switch
(
s
.
type
())
{
case
shape
::
float_type
:
return
"f32"
;
case
shape
::
half_type
:
return
"f16"
;
case
shape
::
bool_type
:
case
shape
::
double_type
:
case
shape
::
uint8_type
:
case
shape
::
int8_type
:
case
shape
::
uint16_type
:
case
shape
::
int16_type
:
case
shape
::
int32_type
:
case
shape
::
int64_type
:
case
shape
::
uint32_type
:
case
shape
::
uint64_type
:
case
shape
::
tuple_type
:
break
;
}
return
nullptr
;
};
const
auto
*
inp_t_s
=
get_type_str
(
inp_t
);
const
auto
*
flt_t_s
=
get_type_str
(
flt_t
);
const
auto
*
out_t_s
=
get_type_str
(
out_t
);
if
(
out_t_s
==
nullptr
||
inp_t_s
==
nullptr
||
flt_t_s
==
nullptr
)
return
result
;
std
::
string
mlir_options
=
"--kernel_name "
+
std
::
string
(
mlir_kernel_name
);
// platform spec
auto
&
device
=
get_context
().
get_current_device
();
char
dev_name
[
64
];
sprintf
(
dev_name
,
"gfx%lu%02lu"
,
device
.
get_device_major
(),
device
.
get_device_minor
());
mlir_options
+=
" --arch "
+
std
::
string
(
dev_name
)
+
" --num_cu "
+
std
::
to_string
(
device
.
get_cu_count
());
// ???
// Conv spec
mlir_options
+=
" --operation "
"conv2d"
" --batchsize "
+
std
::
to_string
(
conv
.
group
)
+
" --groupsize "
+
std
::
to_string
(
1
)
+
" --padding_h "
+
std
::
to_string
(
conv
.
padding
[
0
])
+
" --padding_w "
+
std
::
to_string
(
conv
.
padding
[
1
])
+
" --conv_stride_h "
+
std
::
to_string
(
conv
.
stride
[
0
])
+
" --conv_stride_w "
+
std
::
to_string
(
conv
.
stride
[
1
])
+
" --dilation_h "
+
std
::
to_string
(
conv
.
dilation
[
0
])
+
" --dilation_w "
+
std
::
to_string
(
conv
.
dilation
[
1
]);
// Input spec
mlir_options
+=
" --in_layout "
"NCHWG"
" --in_type "
+
std
::
string
(
inp_t_s
)
+
" --in_channels "
+
std
::
to_string
(
inp_t
.
lens
()[
1
])
+
" --in_h "
+
std
::
to_string
(
inp_t
.
lens
()[
2
])
+
" --in_w "
+
std
::
to_string
(
inp_t
.
lens
()[
3
]);
// Filter spec
mlir_options
+=
" --fil_layout "
"NCHWG"
" --fil_type "
+
std
::
string
(
flt_t_s
)
+
" --fil_h "
+
std
::
to_string
(
flt_t
.
lens
()[
2
])
+
" --fil_w "
+
std
::
to_string
(
flt_t
.
lens
()[
3
]);
// Output spec
mlir_options
+=
" --out_layout "
"NCHWG"
" --out_type "
+
std
::
string
(
out_t_s
)
+
" --out_channels "
+
std
::
to_string
(
out_t
.
lens
()[
1
])
+
" --out_h "
+
std
::
to_string
(
out_t
.
lens
()[
2
])
+
" --out_w "
+
std
::
to_string
(
out_t
.
lens
()[
3
]);
auto
bin_i
=
binary_map
.
find
(
mlir_options
);
if
(
bin_i
==
binary_map
.
end
())
{
size_t
bin_size
=
0
;
using
mlir_handle
=
MIGRAPHX_MANAGE_PTR
(
MiirHandle
,
miirDestroyHandle
);
auto
handle
=
mlir_handle
(
miirCreateHandle
(
mlir_options
.
c_str
()));
if
(
miirLowerBin
(
handle
.
get
())
==
MIIR_SUCCESS
&&
miirBufferGet
(
handle
.
get
(),
nullptr
,
&
bin_size
)
==
MIIR_SUCCESS
)
{
migraphx
::
value
::
binary
bin
(
bin_size
);
if
(
miirBufferGet
(
handle
.
get
(),
reinterpret_cast
<
char
*>
(
bin
.
data
()),
&
bin_size
)
==
MIIR_SUCCESS
)
{
size_t
global_size
;
size_t
block_size
;
if
(
miirGetExecutionDims
(
handle
.
get
(),
&
global_size
,
&
block_size
)
==
MIIR_SUCCESS
)
{
result
=
std
::
make_shared
<
execution_spec
>
(
std
::
move
(
bin
),
global_size
,
block_size
);
}
}
}
binary_map
[
mlir_options
]
=
result
;
}
else
{
result
=
bin_i
->
second
;
}
#else // MIGRAPHX_MLIR_MIOPEN_SUPPORT
(
void
)
op_r
;
#endif // MIGRAPHX_MLIR_MIOPEN_SUPPORT
return
result
;
}
instruction_ref
get_literal
(
uint64_t
value
)
{
auto
fi
=
literal_map
.
find
(
value
);
if
(
fi
!=
literal_map
.
end
())
return
fi
->
second
;
auto
lit
=
mod
->
add_literal
(
value
);
literal_map
.
emplace
(
value
,
lit
);
return
lit
;
}
operation
make_code_object_op
(
instruction_ref
op_r
,
const
std
::
shared_ptr
<
execution_spec
>&
spec
)
{
// each pointer is expanded out to a MemRefDescriptor
auto
inp_t
=
op_r
->
inputs
().
at
(
0
)
->
get_shape
();
auto
flt_t
=
op_r
->
inputs
().
at
(
1
)
->
get_shape
();
auto
out_t
=
op_r
->
get_shape
();
auto
i64
=
shape
(
shape
::
uint64_type
);
std
::
vector
<
shape
>
expected_inputs
=
{
flt_t
,
flt_t
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
inp_t
,
inp_t
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
out_t
,
out_t
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
i64
,
out_t
};
return
migraphx
::
make_op
(
"gpu::code_object"
,
{
{
"code_object"
,
spec
->
binary
},
{
"symbol_name"
,
mlir_kernel_name
},
{
"global"
,
spec
->
global_size
},
{
"local"
,
spec
->
local_size
},
{
"expected_inputs"
,
migraphx
::
to_value
(
expected_inputs
)},
{
"output"
,
migraphx
::
to_value
(
out_t
)},
});
}
void
add_memref_descriptor
(
std
::
vector
<
instruction_ref
>&
refs
,
instruction_ref
inst
)
{
const
size_t
offset
=
0
;
auto
inst_t
=
inst
->
get_shape
();
refs
.
push_back
(
inst
);
refs
.
push_back
(
inst
);
refs
.
push_back
(
get_literal
(
offset
));
// offset
// dim sizes
std
::
transform
(
inst_t
.
lens
().
begin
(),
inst_t
.
lens
().
end
(),
std
::
back_inserter
(
refs
),
[
&
](
const
auto
&
lval
)
{
return
get_literal
(
lval
);
});
refs
.
push_back
(
get_literal
(
1
));
// G
// dim strides
std
::
transform
(
inst_t
.
strides
().
begin
(),
inst_t
.
strides
().
end
(),
std
::
back_inserter
(
refs
),
[
&
](
const
auto
&
lval
)
{
return
get_literal
(
lval
);
});
refs
.
push_back
(
get_literal
(
1
));
// G
}
instruction_ref
insert_allocation
(
instruction_ref
ins
,
const
shape
&
s
)
const
{
return
mod
->
insert_instruction
(
ins
,
hip_allocate
{
s
});
}
void
replace_conv_op
(
instruction_ref
ins
)
{
auto
conv_bin
=
make_mlir_binary
(
ins
);
if
(
conv_bin
)
{
auto
conv
=
make_code_object_op
(
ins
,
conv_bin
);
auto
inp
=
ins
->
inputs
().
at
(
0
);
auto
flt
=
ins
->
inputs
().
at
(
1
);
auto
out
=
insert_allocation
(
ins
,
ins
->
get_shape
());
std
::
vector
<
instruction_ref
>
refs
;
refs
.
reserve
(
3
*
13
+
1
);
add_memref_descriptor
(
refs
,
flt
);
add_memref_descriptor
(
refs
,
inp
);
add_memref_descriptor
(
refs
,
out
);
refs
.
push_back
(
out
);
mod
->
replace_instruction
(
ins
,
conv
,
refs
);
}
}
void
apply
()
{
init
();
for
(
auto
it
:
iterator_for
(
*
mod
))
{
if
(
it
->
name
()
==
"convolution"
)
{
replace_conv_op
(
it
);
}
}
}
};
void
mlir_conv
::
apply
(
module
&
m
)
const
{
mlir_apply
{
&
m
,
this
}.
apply
();
}
}
// namespace gpu
}
// namespace MIGRAPHX_INLINE_NS
}
// namespace migraphx
src/targets/gpu/quant_convolution.cpp
View file @
2ba401f0
...
@@ -67,9 +67,9 @@ argument miopen_quant_convolution::compute(context& ctx,
...
@@ -67,9 +67,9 @@ argument miopen_quant_convolution::compute(context& ctx,
return
args
[
3
];
return
args
[
3
];
}
}
shape
miopen_quant_convolution
::
compile
(
context
&
ctx
,
shape
miopen_quant_convolution
::
find
(
context
&
ctx
,
const
shape
&
output_shape
,
const
shape
&
output_shape
,
std
::
vector
<
shape
>
inputs
)
std
::
vector
<
shape
>
inputs
)
{
{
shape
workspace_shape
{};
shape
workspace_shape
{};
auto
x_desc
=
make_tensor
(
inputs
[
0
],
int8_x4_format
);
auto
x_desc
=
make_tensor
(
inputs
[
0
],
int8_x4_format
);
...
@@ -92,18 +92,18 @@ shape miopen_quant_convolution::compile(context& ctx,
...
@@ -92,18 +92,18 @@ shape miopen_quant_convolution::compile(context& ctx,
x_shape
=
pack_int8_shape
(
x_shape
);
x_shape
=
pack_int8_shape
(
x_shape
);
w_shape
=
pack_int8_shape
(
w_shape
);
w_shape
=
pack_int8_shape
(
w_shape
);
}
}
auto
arg_vec4_x
=
to_gpu
(
generate_argument
(
x_shape
));
auto
x
=
to_gpu
(
generate_argument
(
x_shape
));
auto
arg_vec4_w
=
to_gpu
(
generate_argument
(
w_shape
));
auto
w
=
to_gpu
(
generate_argument
(
w_shape
));
auto
y
=
allocate_gpu
(
output_shape
);
auto
y
=
allocate_gpu
(
output_shape
);
auto
workspace
=
allocate_gpu
(
workspace_shape
);
auto
workspace
=
allocate_gpu
(
workspace_shape
);
int
algo_count
=
1
;
int
algo_count
=
1
;
miopenConvAlgoPerf_t
perf
;
miopenConvAlgoPerf_t
perf
;
auto
status
=
miopenFindConvolutionForwardAlgorithm
(
ctx
.
get_stream
().
get_miopen
(),
auto
status
=
miopenFindConvolutionForwardAlgorithm
(
ctx
.
get_stream
().
get_miopen
(),
x_desc
.
get
(),
x_desc
.
get
(),
arg_vec4_
x
.
implicit
(),
x
.
implicit
(),
w_desc
.
get
(),
w_desc
.
get
(),
arg_vec4_
w
.
implicit
(),
w
.
implicit
(),
cd
.
get
(),
cd
.
get
(),
y_desc
.
get
(),
y_desc
.
get
(),
y
.
implicit
(),
y
.
implicit
(),
...
@@ -114,11 +114,35 @@ shape miopen_quant_convolution::compile(context& ctx,
...
@@ -114,11 +114,35 @@ shape miopen_quant_convolution::compile(context& ctx,
workspace_size
,
workspace_size
,
false
);
false
);
if
(
status
!=
miopenStatusSuccess
)
if
(
status
!=
miopenStatusSuccess
)
{
MIGRAPHX_THROW
(
"MIOpen Quant Convolution: find convolution failed"
);
MIGRAPHX_THROW
(
"QUANT_CONVOLUTION: find convolution failed"
);
algo
=
perf
.
fwd_algo
;
}
handle
=
ctx
.
get_stream
().
get_miopen
();
size_t
solution_count
;
algo
=
perf
.
fwd_algo
;
status
=
miopenConvolutionForwardGetSolutionCount
(
ctx
.
get_stream
().
get_miopen
(),
w_desc
.
get
(),
x_desc
.
get
(),
cd
.
get
(),
y_desc
.
get
(),
&
solution_count
);
if
(
status
!=
miopenStatusSuccess
)
MIGRAPHX_THROW
(
"MIOpen Quant Convolution: get solution count failed"
);
std
::
vector
<
miopenConvSolution_t
>
solutions
(
solution_count
);
status
=
miopenConvolutionForwardGetSolution
(
ctx
.
get_stream
().
get_miopen
(),
w_desc
.
get
(),
x_desc
.
get
(),
cd
.
get
(),
y_desc
.
get
(),
solution_count
,
&
solution_count
,
solutions
.
data
());
if
(
status
!=
miopenStatusSuccess
)
MIGRAPHX_THROW
(
"MIOpen Quant Convolution: get solution failed"
);
solution_id
=
solutions
.
front
().
solution_id
;
return
shape
{
shape
::
int8_type
,
{
perf
.
memory
}};
return
shape
{
shape
::
int8_type
,
{
perf
.
memory
}};
}
}
...
@@ -126,13 +150,29 @@ void miopen_quant_convolution::finalize(context& ctx,
...
@@ -126,13 +150,29 @@ void miopen_quant_convolution::finalize(context& ctx,
const
shape
&
output_shape
,
const
shape
&
output_shape
,
std
::
vector
<
shape
>
inputs
)
std
::
vector
<
shape
>
inputs
)
{
{
if
(
handle
==
ctx
.
get_stream
().
get_miopen
())
if
(
cd
==
nullptr
)
return
;
cd
=
make_conv
(
op
);
// Check that workspace hasn't changed
if
(
solution_id
==
0
)
auto
size
=
inputs
.
at
(
2
).
bytes
();
{
auto
ws
=
compile
(
ctx
,
output_shape
,
std
::
move
(
inputs
));
// Check that workspace hasn't changed
if
(
ws
.
bytes
()
>
size
)
auto
size
=
inputs
.
at
(
2
).
bytes
();
MIGRAPHX_THROW
(
"Workspace has changed during finalization."
);
auto
ws
=
find
(
ctx
,
output_shape
,
inputs
);
if
(
ws
.
bytes
()
>
size
)
MIGRAPHX_THROW
(
"MIOpen Quant Convolution: workspace has changed during finalization."
);
}
auto
x_desc
=
make_tensor
(
inputs
[
0
],
int8_x4_format
);
auto
w_desc
=
make_tensor
(
inputs
[
1
],
int8_x4_format
);
auto
y_desc
=
make_tensor
(
output_shape
);
auto
status
=
miopenConvolutionForwardCompileSolution
(
ctx
.
get_stream
().
get_miopen
(),
w_desc
.
get
(),
x_desc
.
get
(),
cd
.
get
(),
y_desc
.
get
(),
solution_id
);
if
(
status
!=
miopenStatusSuccess
)
MIGRAPHX_THROW
(
"MIOpen Quant Convolution: compile solution failed"
);
}
}
shape
miopen_quant_convolution
::
pack_int8_shape
(
const
shape
&
s
)
const
shape
miopen_quant_convolution
::
pack_int8_shape
(
const
shape
&
s
)
const
...
...
src/targets/gpu/target.cpp
View file @
2ba401f0
...
@@ -53,10 +53,11 @@
...
@@ -53,10 +53,11 @@
#include <migraphx/gpu/compile_ops.hpp>
#include <migraphx/gpu/compile_ops.hpp>
#include <migraphx/gpu/concat_gpu_opt.hpp>
#include <migraphx/gpu/concat_gpu_opt.hpp>
#include <migraphx/gpu/context.hpp>
#include <migraphx/gpu/context.hpp>
#include <migraphx/gpu/device_name.hpp>
#include <migraphx/gpu/fuse_mlir.hpp>
#include <migraphx/gpu/fuse_ops.hpp>
#include <migraphx/gpu/fuse_ops.hpp>
#include <migraphx/gpu/prefuse_ops.hpp>
#include <migraphx/gpu/prefuse_ops.hpp>
#include <migraphx/gpu/lowering.hpp>
#include <migraphx/gpu/lowering.hpp>
#include <migraphx/gpu/mlir_conv.hpp>
#include <migraphx/gpu/pack_int8_args.hpp>
#include <migraphx/gpu/pack_int8_args.hpp>
#include <migraphx/gpu/schedule_model.hpp>
#include <migraphx/gpu/schedule_model.hpp>
#include <migraphx/gpu/sync_device.hpp>
#include <migraphx/gpu/sync_device.hpp>
...
@@ -128,7 +129,8 @@ std::vector<pass> target::get_passes(migraphx::context& gctx, const compile_opti
...
@@ -128,7 +129,8 @@ std::vector<pass> target::get_passes(migraphx::context& gctx, const compile_opti
dead_code_elimination
{},
dead_code_elimination
{},
enable_pass
(
not
enabled
(
MIGRAPHX_DISABLE_POINTWISE_FUSION
{}),
fuse_pointwise
{}),
enable_pass
(
not
enabled
(
MIGRAPHX_DISABLE_POINTWISE_FUSION
{}),
fuse_pointwise
{}),
dead_code_elimination
{},
dead_code_elimination
{},
mlir_conv
{
&
ctx
},
fuse_mlir
{
&
ctx
},
dead_code_elimination
{},
lowering
{
&
ctx
,
options
.
offload_copy
},
lowering
{
&
ctx
,
options
.
offload_copy
},
eliminate_contiguous
{
"gpu::contiguous"
},
eliminate_contiguous
{
"gpu::contiguous"
},
dead_code_elimination
{},
dead_code_elimination
{},
...
@@ -161,7 +163,7 @@ std::vector<pass> target::get_passes(migraphx::context& gctx, const compile_opti
...
@@ -161,7 +163,7 @@ std::vector<pass> target::get_passes(migraphx::context& gctx, const compile_opti
std
::
string
target
::
name
()
const
{
return
"gpu"
;
}
std
::
string
target
::
name
()
const
{
return
"gpu"
;
}
migraphx
::
context
target
::
get_context
()
const
{
return
context
{}
;
}
migraphx
::
context
target
::
get_context
()
const
{
return
context
(
gpu
::
get_device_id
())
;
}
argument
target
::
copy_to
(
const
argument
&
arg
)
const
{
return
gpu
::
to_gpu
(
arg
);
}
argument
target
::
copy_to
(
const
argument
&
arg
)
const
{
return
gpu
::
to_gpu
(
arg
);
}
...
...
src/tf/tf_parser.cpp
View file @
2ba401f0
...
@@ -216,7 +216,7 @@ static std::vector<T> get_data_vals(const google::protobuf::RepeatedField<T>& da
...
@@ -216,7 +216,7 @@ static std::vector<T> get_data_vals(const google::protobuf::RepeatedField<T>& da
std
::
fill
(
data_vals
.
begin
(),
data_vals
.
end
(),
data
[
0
]);
std
::
fill
(
data_vals
.
begin
(),
data_vals
.
end
(),
data
[
0
]);
}
}
else
else
copy
(
data
.
begin
(),
data
.
end
(),
std
::
back_inserter
(
data_vals
));
copy
(
data
.
begin
(),
data
.
end
(),
data_vals
.
begin
(
));
return
data_vals
;
return
data_vals
;
}
}
...
@@ -329,33 +329,37 @@ void tf_parser::parse_node(const std::string& name)
...
@@ -329,33 +329,37 @@ void tf_parser::parse_node(const std::string& name)
auto
&&
node
=
nodes
.
at
(
name
);
auto
&&
node
=
nodes
.
at
(
name
);
if
(
not
is_valid_op
(
node
))
if
(
not
is_valid_op
(
node
))
return
;
return
;
std
::
vector
<
instruction_ref
>
args
;
std
::
vector
<
instruction_ref
>
args
;
for
(
auto
&&
input
:
node
.
input
())
for
(
auto
&&
input
:
node
.
input
())
{
{
// control dependencies (signified by ^ before the name) are ignored
// control dependencies (signified by ^ before the name) are ignored
if
(
contains
(
input
,
"^"
))
if
(
contains
(
input
,
"^"
))
continue
;
continue
;
if
(
nodes
.
count
(
input
)
>
0
)
std
::
string
input_name
=
input
;
// if input has trailing `:0` index then remove it
auto
multi_out_idx
=
input
.
find
(
':'
);
if
(
multi_out_idx
!=
std
::
string
::
npos
&&
input
.
substr
(
multi_out_idx
+
1
)
==
"0"
)
{
input_name
=
input
.
substr
(
0
,
multi_out_idx
);
}
if
(
nodes
.
count
(
input_name
)
>
0
)
{
{
std
::
string
iname
;
// input was from a node with multiple outputs
// input was from a node with multiple outputs
if
(
contains
(
input
,
':'
))
if
(
contains
(
input
_name
,
':'
))
{
{
iname
=
input
.
substr
(
0
,
input
.
find
(
':'
));
i
nput_
name
=
input
_name
.
substr
(
0
,
input
.
find
(
':'
));
}
}
else
else
{
{
iname
=
get_name
(
nodes
.
at
(
input
));
i
nput_
name
=
get_name
(
nodes
.
at
(
input
_name
));
}
}
assert
(
name
!=
iname
);
assert
(
name
!=
i
nput_
name
);
this
->
parse_node
(
iname
);
this
->
parse_node
(
i
nput_
name
);
args
.
push_back
(
instructions
.
at
(
input
));
args
.
push_back
(
instructions
.
at
(
input
_name
));
}
}
else
else
{
{
args
.
push_back
(
instructions
.
at
(
input
));
args
.
push_back
(
instructions
.
at
(
input
_name
));
}
}
}
}
std
::
vector
<
instruction_ref
>
result
;
std
::
vector
<
instruction_ref
>
result
;
...
...
test/CMakeLists.txt
View file @
2ba401f0
...
@@ -137,6 +137,22 @@ if(MIGRAPHX_ENABLE_GPU)
...
@@ -137,6 +137,22 @@ if(MIGRAPHX_ENABLE_GPU)
endforeach
()
endforeach
()
endif
()
endif
()
if
(
MIGRAPHX_ENABLE_FPGA
)
# fpga tests
file
(
GLOB FPGA_TESTS
${
CONFIGURE_DEPENDS
}
fpga/*.cpp
)
foreach
(
TEST
${
FPGA_TESTS
}
)
get_filename_component
(
BASE_NAME
${
TEST
}
NAME_WE
)
add_test_executable
(
test_fpga_
${
BASE_NAME
}
${
TEST
}
)
rocm_clang_tidy_check
(
test_fpga_
${
BASE_NAME
}
)
set_tests_properties
(
test_fpga_
${
BASE_NAME
}
PROPERTIES
COST 10
RESOURCE_LOCK fpga
)
target_link_libraries
(
test_fpga_
${
BASE_NAME
}
migraphx_fpga
)
endforeach
()
endif
()
# Onnx test
# Onnx test
set
(
TEST_ONNX_DIR
${
CMAKE_CURRENT_SOURCE_DIR
}
/onnx
)
set
(
TEST_ONNX_DIR
${
CMAKE_CURRENT_SOURCE_DIR
}
/onnx
)
file
(
GLOB ONNX_TESTS
${
TEST_ONNX_DIR
}
/*.cpp
)
file
(
GLOB ONNX_TESTS
${
TEST_ONNX_DIR
}
/*.cpp
)
...
...
Prev
1
…
4
5
6
7
8
9
10
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment