|
| 1 | +// Copyright (c) 2024 Gregor Daiß |
| 2 | +// |
| 3 | +// Distributed under the Boost Software License, Version 1.0. (See accompanying |
| 4 | +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| 5 | +// |
| 6 | + |
| 7 | +#pragma once |
| 8 | + |
| 9 | +#if defined(OCTOTIGER_HAVE_KOKKOS) && defined(KOKKOS_ENABLE_SYCL) |
| 10 | +#include <CL/sycl.hpp> |
| 11 | +#include <iostream> |
| 12 | + |
| 13 | +namespace octotiger { |
| 14 | +namespace sycl_util { |
| 15 | +#include <CL/sycl.hpp> |
| 16 | + // We encounter segfaults on Intel GPUs when running the normal kernels for the first time after |
| 17 | + // the program starts. This seems to be some initialization issue as we can simply fix it by |
| 18 | + // (non-concurrently) run simple dummy kernel first right after starting octotiger |
| 19 | + // (presumably initializes something within the intel gpu runtime). |
| 20 | + // Curiousely we have to do this not once per program, but once per lib (octolib and hydrolib). |
| 21 | + // |
| 22 | + // Somewhat of an ugly workaround but it does the trick and allows us to target Intel GPUs as |
| 23 | + // Octo-Tiger runs as expected after applying this workaround. |
| 24 | + |
| 25 | + // TODO(daissgr) Check again in the future to see if the runtime has matured and we don't need this anymore. |
| 26 | + // (last check was 02/2024) |
| 27 | + |
| 28 | + /// Utility function working around segfault on Intel GPU. Initializes something within the runtime by runnning |
| 29 | + ///a dummy kernel |
| 30 | + template<const char *modulename> // modulename must be unique within octotiger for this to work |
| 31 | + int touch_sycl_device_by_running_a_dummy_kernel(void) { |
| 32 | + try { |
| 33 | + cl::sycl::queue q(cl::sycl::default_selector_v, cl::sycl::property::queue::in_order{}); |
| 34 | + cl::sycl::event my_kernel_event = q.submit( |
| 35 | + [&](cl::sycl::handler& h) { |
| 36 | + h.parallel_for(512, [=](auto i) {}); |
| 37 | + }, |
| 38 | + cl::sycl::detail::code_location{}); |
| 39 | + my_kernel_event.wait(); |
| 40 | + std::cout << "SYCL runtime has been initialized for " << modulename << "!" << std::endl; |
| 41 | + } catch (sycl::exception const& e) { |
| 42 | + std::cerr << "(NON-FATAL) ERROR: Caught sycl::exception during SYCL dummy kernel!\n"; |
| 43 | + std::cerr << " {what}: " << e.what() << "\n "; |
| 44 | + std::cerr << "Continuing for now as error only occured in the dummy kernel meant to " |
| 45 | + << "initialize the device by first touch...\n"; |
| 46 | + return 2; |
| 47 | + |
| 48 | + } |
| 49 | + return 1; |
| 50 | + } |
| 51 | + |
| 52 | +} // namespace sycl_util |
| 53 | +} // namespace octotiger |
| 54 | + |
| 55 | +#endif |
0 commit comments