30 [[nodiscard]]
bool probe(
int cuda_device, std::string_view model_file,
31 std::string_view layer,
int iterations,
32 float strength,
float feedback,
float zoom,
33 float rotation_degrees,
int max_dimension,
34 bool use_half,
int target_channel,
35 int octaves,
float octave_scale,
36 int jitter,
int smoothing,
38 std::ostream &error) {
39 output <<
"Deep Dream: enabled\n"
40 <<
"LibTorch version: " << TORCH_VERSION <<
'\n';
41#ifdef ACMXVK_WITH_MXVK_CUDA
42 output <<
"Deep Dream CUDA/Vulkan interop: enabled\n";
44 output <<
"Deep Dream CUDA/Vulkan interop: unavailable "
45 "(MXVK has no CUDA interop)\n";
49 if (!autograd_smoke_test(torch::Device(torch::kCPU))) {
50 error <<
"Deep Dream LibTorch CPU autograd smoke test failed\n";
53 output <<
"LibTorch CPU autograd: ready\n";
55 const c10::DeviceIndex device_count = torch::cuda::device_count();
56 output <<
"LibTorch CUDA devices: "
57 <<
static_cast<int>(device_count) <<
'\n';
58 if (!torch::cuda::is_available() || device_count == 0) {
59 output <<
"LibTorch CUDA autograd: unavailable "
60 "(no CUDA device visible)\n";
61 if (!model_file.empty()) {
62 error <<
"Deep Dream model inspection requires an "
63 "available CUDA device\n";
68 if (cuda_device < 0 || cuda_device >= device_count) {
69 error <<
"Deep Dream CUDA device index " << cuda_device
70 <<
" is outside the available range 0-"
71 << (device_count - 1) <<
'\n';
75 const torch::Device device(torch::kCUDA, cuda_device);
76 if (!autograd_smoke_test(device)) {
77 error <<
"Deep Dream LibTorch CUDA autograd smoke test failed "
79 << cuda_device <<
'\n';
82 torch::cuda::synchronize(cuda_device);
83 output <<
"LibTorch CUDA autograd: ready on device " << cuda_device
86 << (torch::cuda::cudnn_is_available() ?
"ready" :
"unavailable")
89 if (!model_file.empty()) {
91 Model::load(model_file, cuda_device, layer, use_half);
93 output <<
"Deep Dream target channel: ";
94 if (target_channel < 0) {
97 output << target_channel <<
'\n';
99 const int test_size = std::max(
101 cv::Mat test_image(test_size, test_size, CV_8UC4);
102 for (
int y = 0; y < test_image.rows; ++y) {
103 for (
int x = 0; x < test_image.cols; ++x) {
104 test_image.at<cv::Vec4b>(y, x) = cv::Vec4b{
105 static_cast<std::uint8_t
>((x * 255) /
106 (test_image.cols - 1)),
107 static_cast<std::uint8_t
>((y * 255) /
108 (test_image.rows - 1)),
109 static_cast<std::uint8_t
>(((x + y) * 255) /
111 test_image.rows - 2)),
118 rotation_degrees, max_dimension,
119 target_channel, octaves,
120 octave_scale, jitter, smoothing});
121 output << std::fixed << std::setprecision(6)
122 <<
"Deep Dream gradient ascent: ready"
125 <<
", mean pixel change="
130 <<
", smoothing=" << smoothing <<
")\n";
131 if (feedback > 0.0F) {
135 zoom, rotation_degrees,
136 max_dimension, target_channel,
137 octaves, octave_scale, jitter,
139 output <<
"Deep Dream temporal feedback: ready"
140 <<
" (blend=" << feedback <<
", zoom=" << zoom
141 <<
", rotation=" << rotation_degrees
142 <<
", next-frame change="
146 }
catch (
const std::exception &exception) {
147 error <<
"Deep Dream LibTorch probe failed: " << exception.what()