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
composable_kernel
Commits
6e4a1075
Commit
6e4a1075
authored
Sep 28, 2023
by
Paul
Browse files
Format
parent
94bfa502
Changes
28
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
426 additions
and
0 deletions
+426
-0
host/test/rtc/include/rtc/hip.hpp
host/test/rtc/include/rtc/hip.hpp
+14
-0
host/test/rtc/include/rtc/kernel.hpp
host/test/rtc/include/rtc/kernel.hpp
+62
-0
host/test/rtc/include/rtc/manage_ptr.hpp
host/test/rtc/include/rtc/manage_ptr.hpp
+36
-0
host/test/rtc/include/rtc/tmp_dir.hpp
host/test/rtc/include/rtc/tmp_dir.hpp
+24
-0
host/test/rtc/src/compile_kernel.cpp
host/test/rtc/src/compile_kernel.cpp
+95
-0
host/test/rtc/src/hip.cpp
host/test/rtc/src/hip.cpp
+26
-0
host/test/rtc/src/kernel.cpp
host/test/rtc/src/kernel.cpp
+121
-0
host/test/rtc/src/tmp_dir.cpp
host/test/rtc/src/tmp_dir.cpp
+48
-0
No files found.
host/test/rtc/include/rtc/hip.hpp
0 → 100644
View file @
6e4a1075
#ifndef GUARD_HOST_TEST_RTC_INCLUDE_RTC_HIP
#define GUARD_HOST_TEST_RTC_INCLUDE_RTC_HIP
#include <hip/hip_runtime_api.h>
#include <string>
namespace
rtc
{
std
::
string
get_device_name
();
std
::
string
hip_error
(
int
error
);
}
// namespace rtc
#endif
host/test/rtc/include/rtc/kernel.hpp
0 → 100644
View file @
6e4a1075
#ifndef GUARD_HOST_TEST_RTC_INCLUDE_RTC_KERNEL
#define GUARD_HOST_TEST_RTC_INCLUDE_RTC_KERNEL
#include <hip/hip_runtime_api.h>
#include <memory>
#include <string>
#include <vector>
namespace
rtc
{
struct
kernel_argument
{
template
<
class
T
,
class
U
=
std
::
remove_reference_t
<
T
>,
class
=
std
::
enable_if_t
<
not
std
::
is_base_of
<
kernel_argument
,
T
>
{}
>>
kernel_argument
(
T
&&
x
)
:
size
(
sizeof
(
U
)),
align
(
alignof
(
U
)),
data
(
&
x
)
// NOLINT
{
}
std
::
size_t
size
;
std
::
size_t
align
;
void
*
data
;
};
std
::
vector
<
char
>
pack_args
(
const
std
::
vector
<
kernel_argument
>&
args
);
struct
kernel_impl
;
struct
kernel
{
kernel
()
=
default
;
kernel
(
const
char
*
image
,
const
std
::
string
&
name
);
template
<
class
T
>
kernel
(
const
std
::
vector
<
T
>&
image
,
const
std
::
string
&
name
)
:
kernel
(
reinterpret_cast
<
const
char
*>
(
image
.
data
()),
name
)
{
static_assert
(
sizeof
(
T
)
==
1
,
"Only byte types"
);
}
void
launch
(
hipStream_t
stream
,
std
::
size_t
global
,
std
::
size_t
local
,
const
std
::
vector
<
kernel_argument
>&
args
)
const
;
void
launch
(
hipStream_t
stream
,
std
::
size_t
global
,
std
::
size_t
local
,
std
::
vector
<
void
*>
args
)
const
;
template
<
class
...
Ts
>
auto
launch
(
hipStream_t
stream
,
std
::
size_t
global
,
std
::
size_t
local
,
Ts
...
zs
)
const
{
return
[
=
](
auto
&&
...
xs
)
{
launch
(
stream
,
global
,
local
,
std
::
vector
<
kernel_argument
>
{
xs
...},
zs
...);
};
}
private:
std
::
shared_ptr
<
kernel_impl
>
impl
;
};
}
// namespace rtc
#endif
host/test/rtc/include/rtc/manage_ptr.hpp
0 → 100644
View file @
6e4a1075
#ifndef GUARD_HOST_TEST_RTC_INCLUDE_RTC_MANAGE_POINTER
#define GUARD_HOST_TEST_RTC_INCLUDE_RTC_MANAGE_POINTER
#include <type_traits>
#include <memory>
namespace
rtc
{
template
<
class
F
,
F
f
>
struct
manage_deleter
{
template
<
class
T
>
void
operator
()(
T
*
x
)
const
{
if
(
x
!=
nullptr
)
{
(
void
)
f
(
x
);
}
}
};
struct
null_deleter
{
template
<
class
T
>
void
operator
()(
T
*
)
const
{
}
};
template
<
class
T
,
class
F
,
F
f
>
using
manage_ptr
=
std
::
unique_ptr
<
T
,
manage_deleter
<
F
,
f
>>
;
#define RTC_MANAGE_PTR(T, F) rtc::manage_ptr<std::remove_pointer_t<T>, decltype(&F), &F>
}
// namespace rtc
#endif
host/test/rtc/include/rtc/tmp_dir.hpp
0 → 100644
View file @
6e4a1075
#ifndef GUARD_HOST_TEST_RTC_INCLUDE_RTC_TMP_DIR
#define GUARD_HOST_TEST_RTC_INCLUDE_RTC_TMP_DIR
#include <string>
#include <filesystem>
namespace
rtc
{
struct
tmp_dir
{
std
::
filesystem
::
path
path
;
tmp_dir
(
const
std
::
string
&
prefix
=
""
);
void
execute
(
const
std
::
string
&
cmd
)
const
;
tmp_dir
(
tmp_dir
const
&
)
=
delete
;
tmp_dir
&
operator
=
(
tmp_dir
const
&
)
=
delete
;
~
tmp_dir
();
};
}
// namespace rtc
#endif
host/test/rtc/src/compile_kernel.cpp
0 → 100644
View file @
6e4a1075
#include "rtc/hip.hpp"
#include <rtc/compile_kernel.hpp>
#include <rtc/tmp_dir.hpp>
#include <stdexcept>
#include <iostream>
#include <fstream>
#include <cassert>
namespace
rtc
{
template
<
class
T
>
T
generic_read_file
(
const
std
::
string
&
filename
,
size_t
offset
=
0
,
size_t
nbytes
=
0
)
{
std
::
ifstream
is
(
filename
,
std
::
ios
::
binary
|
std
::
ios
::
ate
);
if
(
nbytes
==
0
)
{
// if there is a non-zero offset and nbytes is not set,
// calculate size of remaining bytes to read
nbytes
=
is
.
tellg
();
if
(
offset
>
nbytes
)
throw
std
::
runtime_error
(
"offset is larger than file size"
);
nbytes
-=
offset
;
}
if
(
nbytes
<
1
)
throw
std
::
runtime_error
(
"Invalid size for: "
+
filename
);
is
.
seekg
(
offset
,
std
::
ios
::
beg
);
T
buffer
(
nbytes
,
0
);
if
(
not
is
.
read
(
&
buffer
[
0
],
nbytes
))
throw
std
::
runtime_error
(
"Error reading file: "
+
filename
);
return
buffer
;
}
std
::
vector
<
char
>
read_buffer
(
const
std
::
string
&
filename
,
size_t
offset
=
0
,
size_t
nbytes
=
0
)
{
return
generic_read_file
<
std
::
vector
<
char
>>
(
filename
,
offset
,
nbytes
);
}
std
::
string
read_string
(
const
std
::
string
&
filename
)
{
return
generic_read_file
<
std
::
string
>
(
filename
);
}
void
write_buffer
(
const
std
::
string
&
filename
,
const
char
*
buffer
,
std
::
size_t
size
)
{
std
::
ofstream
os
(
filename
);
os
.
write
(
buffer
,
size
);
}
void
write_buffer
(
const
std
::
string
&
filename
,
const
std
::
vector
<
char
>&
buffer
)
{
write_buffer
(
filename
,
buffer
.
data
(),
buffer
.
size
());
}
void
write_string
(
const
std
::
string
&
filename
,
const
std
::
string
&
buffer
)
{
write_buffer
(
filename
,
buffer
.
data
(),
buffer
.
size
());
}
std
::
string
compiler
()
{
return
"/opt/rocm/llvm/bin/clang++ -x hip --cuda-device-only"
;
}
kernel
compile_kernel
(
const
std
::
vector
<
src_file
>&
srcs
,
compile_options
options
)
{
assert
(
not
srcs
.
empty
());
tmp_dir
td
{
"compile"
};
options
.
flags
+=
" -I. -O3"
;
options
.
flags
+=
" -std=c++17"
;
options
.
flags
+=
" --offload-arch="
+
get_device_name
();
std
::
string
out
;
for
(
const
auto
&
src
:
srcs
)
{
std
::
filesystem
::
path
full_path
=
td
.
path
/
src
.
path
;
std
::
filesystem
::
path
parent_path
=
full_path
.
parent_path
();
std
::
filesystem
::
create_directories
(
parent_path
);
write_string
(
full_path
.
string
(),
src
.
content
);
if
(
src
.
path
.
extension
().
string
()
==
".cpp"
)
{
options
.
flags
+=
" -c "
+
src
.
path
.
filename
().
string
();
if
(
out
.
empty
())
out
=
src
.
path
.
stem
().
string
()
+
".o"
;
}
}
options
.
flags
+=
" -o "
+
out
;
td
.
execute
(
compiler
()
+
options
.
flags
);
auto
out_path
=
td
.
path
/
out
;
if
(
not
std
::
filesystem
::
exists
(
out_path
))
throw
std
::
runtime_error
(
"Output file missing: "
+
out
);
auto
obj
=
read_buffer
(
out_path
.
string
());
return
kernel
{
obj
.
data
(),
options
.
kernel_name
};
}
}
// namespace rtc
host/test/rtc/src/hip.cpp
0 → 100644
View file @
6e4a1075
#include <rtc/hip.hpp>
#include <stdexcept>
namespace
rtc
{
std
::
string
hip_error
(
int
error
)
{
return
hipGetErrorString
(
static_cast
<
hipError_t
>
(
error
));
}
int
get_device_id
()
{
int
device
;
auto
status
=
hipGetDevice
(
&
device
);
if
(
status
!=
hipSuccess
)
throw
std
::
runtime_error
(
"No device"
);
return
device
;
}
std
::
string
get_device_name
()
{
hipDeviceProp_t
props
{};
auto
status
=
hipGetDeviceProperties
(
&
props
,
get_device_id
());
if
(
status
!=
hipSuccess
)
throw
std
::
runtime_error
(
"Failed to get device properties"
);
return
props
.
gcnArchName
;
}
}
// namespace rtc
host/test/rtc/src/kernel.cpp
0 → 100644
View file @
6e4a1075
#include <rtc/kernel.hpp>
#include <rtc/manage_ptr.hpp>
#include <rtc/hip.hpp>
#include <cassert>
// extern declare the function since hip/hip_ext.h header is broken
extern
hipError_t
hipExtModuleLaunchKernel
(
hipFunction_t
,
// NOLINT
uint32_t
,
uint32_t
,
uint32_t
,
uint32_t
,
uint32_t
,
uint32_t
,
size_t
,
hipStream_t
,
void
**
,
void
**
,
hipEvent_t
=
nullptr
,
hipEvent_t
=
nullptr
,
uint32_t
=
0
);
namespace
rtc
{
std
::
vector
<
char
>
pack_args
(
const
std
::
vector
<
kernel_argument
>&
args
)
{
std
::
vector
<
char
>
kernargs
;
for
(
auto
&&
arg
:
args
)
{
std
::
size_t
n
=
arg
.
size
;
const
auto
*
p
=
static_cast
<
const
char
*>
(
arg
.
data
);
// Insert padding
std
::
size_t
padding
=
(
arg
.
align
-
(
kernargs
.
size
()
%
arg
.
align
))
%
arg
.
align
;
kernargs
.
insert
(
kernargs
.
end
(),
padding
,
0
);
kernargs
.
insert
(
kernargs
.
end
(),
p
,
p
+
n
);
}
return
kernargs
;
}
using
hip_module_ptr
=
RTC_MANAGE_PTR
(
hipModule_t
,
hipModuleUnload
);
struct
kernel_impl
{
hip_module_ptr
module
=
nullptr
;
hipFunction_t
fun
=
nullptr
;
};
hip_module_ptr
load_module
(
const
char
*
image
)
{
hipModule_t
raw_m
;
auto
status
=
hipModuleLoadData
(
&
raw_m
,
image
);
hip_module_ptr
m
{
raw_m
};
if
(
status
!=
hipSuccess
)
throw
std
::
runtime_error
(
"Failed to load module: "
+
hip_error
(
status
));
return
m
;
}
kernel
::
kernel
(
const
char
*
image
,
const
std
::
string
&
name
)
:
impl
(
std
::
make_shared
<
kernel_impl
>
())
{
impl
->
module
=
load_module
(
image
);
auto
status
=
hipModuleGetFunction
(
&
impl
->
fun
,
impl
->
module
.
get
(),
name
.
c_str
());
if
(
hipSuccess
!=
status
)
throw
std
::
runtime_error
(
"Failed to get function: "
+
name
+
": "
+
hip_error
(
status
));
}
void
launch_kernel
(
hipFunction_t
fun
,
hipStream_t
stream
,
std
::
size_t
global
,
std
::
size_t
local
,
void
*
kernargs
,
std
::
size_t
size
)
{
assert
(
global
>
0
);
assert
(
local
>
0
);
void
*
config
[]
=
{
HIP_LAUNCH_PARAM_BUFFER_POINTER
,
kernargs
,
HIP_LAUNCH_PARAM_BUFFER_SIZE
,
&
size
,
HIP_LAUNCH_PARAM_END
};
auto
status
=
hipExtModuleLaunchKernel
(
fun
,
global
,
1
,
1
,
local
,
1
,
1
,
0
,
stream
,
nullptr
,
reinterpret_cast
<
void
**>
(
&
config
),
nullptr
,
nullptr
);
if
(
status
!=
hipSuccess
)
throw
std
::
runtime_error
(
"Failed to launch kernel: "
+
hip_error
(
status
));
}
void
kernel
::
launch
(
hipStream_t
stream
,
std
::
size_t
global
,
std
::
size_t
local
,
std
::
vector
<
void
*>
args
)
const
{
assert
(
impl
!=
nullptr
);
void
*
kernargs
=
args
.
data
();
std
::
size_t
size
=
args
.
size
()
*
sizeof
(
void
*
);
launch_kernel
(
impl
->
fun
,
stream
,
global
,
local
,
kernargs
,
size
);
}
void
kernel
::
launch
(
hipStream_t
stream
,
std
::
size_t
global
,
std
::
size_t
local
,
const
std
::
vector
<
kernel_argument
>&
args
)
const
{
assert
(
impl
!=
nullptr
);
std
::
vector
<
char
>
kernargs
=
pack_args
(
args
);
std
::
size_t
size
=
kernargs
.
size
();
launch_kernel
(
impl
->
fun
,
stream
,
global
,
local
,
kernargs
.
data
(),
size
);
}
}
// namespace rtc
\ No newline at end of file
host/test/rtc/src/tmp_dir.cpp
0 → 100644
View file @
6e4a1075
#include <rtc/tmp_dir.hpp>
#include <algorithm>
#include <random>
#include <thread>
#include <unistd.h>
namespace
rtc
{
std
::
string
random_string
(
std
::
string
::
size_type
length
)
{
static
const
std
::
string
&
chars
=
"0123456789"
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
;
std
::
mt19937
rg
{
std
::
random_device
{}()};
std
::
uniform_int_distribution
<
std
::
string
::
size_type
>
pick
(
0
,
chars
.
length
()
-
1
);
std
::
string
str
(
length
,
0
);
std
::
generate
(
str
.
begin
(),
str
.
end
(),
[
&
]
{
return
chars
[
pick
(
rg
)];
});
return
str
;
}
std
::
string
unique_string
(
const
std
::
string
&
prefix
)
{
auto
pid
=
getpid
();
auto
tid
=
std
::
this_thread
::
get_id
();
auto
clk
=
std
::
chrono
::
steady_clock
::
now
().
time_since_epoch
().
count
();
std
::
stringstream
ss
;
ss
<<
std
::
hex
<<
prefix
<<
"-"
<<
pid
<<
"-"
<<
tid
<<
"-"
<<
clk
<<
"-"
<<
random_string
(
16
);
return
ss
.
str
();
}
tmp_dir
::
tmp_dir
(
const
std
::
string
&
prefix
)
:
path
(
std
::
filesystem
::
temp_directory_path
()
/
unique_string
(
prefix
.
empty
()
?
"ck-rtc"
:
"ck-rtc-"
+
prefix
))
{
std
::
filesystem
::
create_directories
(
this
->
path
);
}
void
tmp_dir
::
execute
(
const
std
::
string
&
cmd
)
const
{
std
::
string
s
=
"cd "
+
path
.
string
()
+
"; "
+
cmd
;
std
::
system
(
s
.
c_str
());
}
tmp_dir
::~
tmp_dir
()
{
std
::
filesystem
::
remove_all
(
this
->
path
);
}
}
// namespace rtc
\ No newline at end of file
Prev
1
2
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