Skip to content

Commit

Permalink
Add handling for the new Result type
Browse files Browse the repository at this point in the history
The caller of a function returning Result is obligated to check the
return type because failing to handle an error properly might put the
library into an unspecified and invalid state!
  • Loading branch information
Weckyy702 committed Dec 14, 2022
1 parent 01d03ba commit 8995de5
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 23 deletions.
6 changes: 4 additions & 2 deletions doc/examples/compute_transfer_overlap/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,10 @@ auto main()-> int {
auto t_1 = vuh::copy_async(device_begin(d_y), device_begin(d_y) + tile_size, begin(y));

// We need result to be available to init the copy-back of the second chunk. Hence blocking call.
program({tile_size, a}, vuh::array_view(d_y, tile_size, arr_size)
, vuh::array_view(d_x, tile_size, arr_size));
if(program({tile_size, a}, vuh::array_view(d_y, tile_size, arr_size),
vuh::array_view(d_x, tile_size, arr_size)).is_error()) {
return 1;
}
auto t_2 = vuh::copy_async(device_begin(d_y) + tile_size, device_end(d_y), begin(y) + tile_size);
t_1.wait(); // explicitly wait for the first chunk here (think of staging buffers and destruction order)
}
Expand Down
5 changes: 4 additions & 1 deletion doc/examples/mandelbrot/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@ auto main()-> int {
using Specs = vuh::typelist<uint32_t, uint32_t>; // width, height of a workgroup
struct Params{uint32_t width; uint32_t height;}; // width, height of an image
auto program = vuh::Program<Specs, Params>(device, "mandelbrot.spv");
program.grid(vuh::div_up(width, 32), vuh::div_up(height, 32))
const auto result = program.grid(vuh::div_up(width, 32), vuh::div_up(height, 32))
.spec(32, 32)({width, height}, mandel); // run the kernel

if(result.is_error())
return (int)result.error();

write_ppm("mandelebrot.ppm", mandel.data(), width, height);

return 0;
Expand Down
5 changes: 4 additions & 1 deletion doc/examples/saxpy/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ auto main()-> int {
using Specs = vuh::typelist<uint32_t>;
struct Params{uint32_t size; float a;};
auto program = vuh::Program<Specs, Params>(device, "saxpy.spv"); // define the kernel by linking interface and spir-v implementation
program.grid(128/64).spec(64)({128, a}, d_y, d_x); // run once, wait for completion
const auto result = program.grid(128/64).spec(64)({128, a}, d_y, d_x); // run once, wait for completion
if(result.is_error())
return (int)result.error();

d_y.toHost(begin(y)); // copy data back to host

return 0;
Expand Down
15 changes: 9 additions & 6 deletions src/include/vuh/program.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ namespace vuh {
if(!Base::_pipeline){ // handle multiple rebind
init_pipelayout(args...);
Base::alloc_descriptor_sets(args...);
Base::init_pipeline();
VUH_TRY_VOID(Base::init_pipeline())
}
create_command_buffer(p, args...);
return *this;
Expand All @@ -447,18 +447,19 @@ namespace vuh {
/// Run program with provided parameters.
/// @pre grid dimensions should be specified before calling this.
template<class... Arrs>
bind(params, args...);
auto operator()(const Params& params, Arrs&&... args)-> Result<void> {
VUH_TRY_VOID(bind(params, args...))
Base::run();

return vk::Result::eSuccess;
}

/// Initiate execution of the program with provided parameters and immidiately return.
/// @return Delayed<Compute> object for synchronization with host.
/// @pre grid dimensions should be specified before callind this.
template<class... Arrs>
bind(params, args...);
auto run_async(const Params& params, Arrs&&... args)-> Result<Delayed<detail::Compute>> {
VUH_TRY_VOID(bind(params, args...));
return Base::run_async();
}
private: // helpers
Expand Down Expand Up @@ -532,7 +533,7 @@ namespace vuh {
if(!Base::_pipeline){ // handle multiple rebind
Base::init_pipelayout(std::array<vk::PushConstantRange, 0>{}, args...);
Base::alloc_descriptor_sets(args...);
Base::init_pipeline();
VUH_TRY_VOID(Base::init_pipeline());
}
Base::command_buffer_begin(args...);
Base::command_buffer_end();
Expand All @@ -542,17 +543,19 @@ namespace vuh {
/// Run program with provided parameters.
/// @pre grid dimensions should be specified before calling this.
template<class... Arrs>
bind(args...);
auto operator()(Arrs&&... args)-> Result<void> {
VUH_TRY_VOID(bind(args...));
Base::run();

return vk::Result::eSuccess;
}

/// Initiate execution of the program with provided parameters and immidiately return.
/// @return Delayed<Compute> object for synchronization with host.
/// @pre grid dimensions should be specified before callind this.
template<class... Arrs>
bind(args...);
auto run_async(Arrs&&... args)-> Result<vuh::Delayed<detail::Compute>> {
VUH_TRY_VOID(bind(args...));
return Base::run_async();
}
}; // class Program
Expand Down
14 changes: 8 additions & 6 deletions test/correctness/saxpy_async_t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ TEST_CASE("data transfer and computation interleaved. sync host side.", "[correc
using Specs = vuh::typelist<uint32_t>;
struct Params{uint32_t size; float a;};
auto program = vuh::Program<Specs, Params>(device, "../shaders/saxpy.spv"); // define the kernel by linking interface and spir-v implementation
auto fence_p = program.grid(tile_size/grid_x).spec(grid_x)

VUH_TRY_TEST(program.grid(tile_size/grid_x).spec(grid_x)
.run_async({tile_size, a}, vuh::array_view(d_y, 0, tile_size)
, vuh::array_view(d_x, 0, tile_size));
, vuh::array_view(d_x, 0, tile_size)), fence_p, "processing");
fence_cpy = vuh::copy_async(begin(y) + tile_size, end(y), device_begin(d_y) + tile_size);
fence_cpx = vuh::copy_async(begin(x) + tile_size, end(x), device_begin(d_x) + tile_size);

Expand All @@ -57,8 +58,9 @@ TEST_CASE("data transfer and computation interleaved. sync host side.", "[correc
, begin(y));
fence_cpy.wait();
fence_cpx.wait();
fence_p = program.run_async({tile_size, a}, vuh::array_view(d_y, tile_size, arr_size)
, vuh::array_view(d_x, tile_size, arr_size));
VUH_TRY_TEST(program.run_async({tile_size, a}, vuh::array_view(d_y, tile_size, arr_size)
, vuh::array_view(d_x, tile_size, arr_size)), _fence_p, "?");
fence_p = std::move(_fence_p);

// wait for everything to complete
fence_p.wait();
Expand Down Expand Up @@ -91,8 +93,8 @@ TEST_CASE("data transfer and computation interleaved. sync host side.", "[correc
{ // phase 3. copy back first result tile, run kernel on second tiles
auto f_y1 = vuh::copy_async(device_begin(d_y), device_begin(d_y) + tile_size, begin(y));

program.run_async({tile_size, a}, vuh::array_view(d_y, tile_size, arr_size)
, vuh::array_view(d_x, tile_size, arr_size));
REQUIRE(!program.run_async({tile_size, a}, vuh::array_view(d_y, tile_size, arr_size)
, vuh::array_view(d_x, tile_size, arr_size)).is_error());
auto f_y2 = vuh::copy_async(device_begin(d_y) + tile_size, device_end(d_y), begin(y) + tile_size);
f_y1.wait();
}
Expand Down
14 changes: 7 additions & 7 deletions test/correctness/saxpy_sync_t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,30 +30,30 @@ TEST_CASE("saxpy_once_1D", "[program][correctness]"){
using Specs = vuh::typelist<uint32_t>;
struct Params{uint32_t size; float a;};
auto program = vuh::Program<Specs, Params>(device, "../shaders/saxpy.spv"); // define the kernel by linking interface and spir-v implementation
program.grid(128/64).spec(64)({128, a}, d_y, d_x); // run once, wait for completion
REQUIRE(!program.grid(128/64).spec(64)({128, a}, d_y, d_x).is_error()); // run once, wait for completion
d_y.toHost(begin(y)); // copy data back to host

REQUIRE(y == approx(out_ref).eps(1.e-5).verbose());
}
SECTION("no specialization constants"){
struct Params{uint32_t size; float a;};
auto program = vuh::Program<vuh::typelist<>, Params>(device, "../shaders/saxpy_nospec.spv");
program.grid(2)({128, a}, d_y, d_x);
REQUIRE(!program.grid(2)({128, a}, d_y, d_x).is_error());
d_y.toHost(begin(y));

REQUIRE(y == approx(out_ref).eps(1.e-5));
}
SECTION("no push constants"){
using Specs = vuh::typelist<uint32_t>;
auto program = vuh::Program<Specs>(device, "../shaders/saxpy_nopush.spv");
program.grid(2).spec(64)(d_y, d_x);
REQUIRE(!program.grid(2).spec(64)(d_y, d_x).is_error());
d_y.toHost(begin(y));

REQUIRE(y == approx(out_ref).eps(1.e-5));
}
SECTION("no push or specialization constants"){
auto program = vuh::Program<>(device, "../shaders/saxpy_noth.spv");
program.grid(2)(d_y, d_x);
REQUIRE(!program.grid(2)(d_y, d_x).is_error());
d_y.toHost(begin(y));

REQUIRE(y == approx(out_ref).eps(1.e-5));
Expand Down Expand Up @@ -81,9 +81,9 @@ TEST_CASE("saxpy_repeated_1D", "[correctness]"){
using Specs = vuh::typelist<uint32_t>;
struct Params{uint32_t size; float a;};
auto program = vuh::Program<Specs, Params>(device, "../shaders/saxpy.spv");
program.grid(128/64) // set number of wrokgroups to run
REQUIRE(!program.grid(128/64) // set number of wrokgroups to run
.spec(64) // set the specialization constants
.bind({128, a}, d_y, d_x); // bind arrays and non-array parameters
.bind({128, a}, d_y, d_x).is_error()); // bind arrays and non-array parameters
for(size_t i = 0; i < n_repeat; ++i){
program.run();
}
Expand All @@ -97,7 +97,7 @@ TEST_CASE("saxpy_repeated_1D", "[correctness]"){
auto program = vuh::Program<Specs, Params>(device, "../shaders/saxpy.spv");
program.grid(128/64).spec(64);
for(size_t i = 0; i < n_repeat; ++i){
program({128, a}, d_y, d_x);
REQUIRE(!program({128, a}, d_y, d_x).is_error());
}
d_y.toHost(begin(y));

Expand Down

0 comments on commit 8995de5

Please sign in to comment.