Source browser
tests/test_math_gpu.cpp
Read the complete file below or download its original bytes. Line numbers provide stable links to a declaration or processing step.
File fingerprint
1/** @file test_math_gpu.cpp
2 * The native math shader is compiled through the generated GCC adapter and
3 * dispatched on CPU and every enabled GLES/GL profile. Known references check
4 * formulas independently. GPU runs additionally compare against CPU results.
5 */
6#include "examples/runner.hpp" // Include examples/runner.hpp declarations.
7#include <cstdint> // Include cstdint declarations.
8#include <vector> // Include vector declarations.
9
10namespace { // Group these helpers within their namespace.
11const float expected[] = { // Declare expected for the following calculation.
12 -3, 6, -3, 32, 5, 0.6f, 0.8f, 1, -1, 0.5f, -0.5f, 0.75f, 0, 2, 2, -2, -2, -88, // Complete this expression or declaration.
13 11, 16, 8, 18, 7, 22, 1, 0, 4, 3, 15, 16, 2, 1, 3, 3, 2.5f, 4, // Complete this expression or declaration.
14 3, 0.5f, 0, 1, 90, 0.25f, -1, -0.25f, 4, 4, -2, -1, 1, 0.5f, -1, 1, 2.5f, 9}; // Complete this expression or declaration.
15const std::uint32_t expected_bits[] = {0x3f800000u, // Declare expected bits for the following calculation.
16 0x80000000u, // Complete this expression or declaration.
17 32u, // Complete this expression or declaration.
18 3u, // Complete this expression or declaration.
19 0u, // Complete this expression or declaration.
20 0x80000000u, // Complete this expression or declaration.
21 0xffffffffu, // Complete this expression or declaration.
22 0xff03u, // Complete this expression or declaration.
23 1u, // Complete this expression or declaration.
24 1u, // Complete this expression or declaration.
25 0xfffffffeu, // Complete this expression or declaration.
26 1u, // Complete this expression or declaration.
27 0xc0003c00u, // Complete this expression or declaration.
28 0xffff0000u, // Complete this expression or declaration.
29 0x00ff00ffu, // Complete this expression or declaration.
30 0xffffffffu, // Complete this expression or declaration.
31 1u}; // Complete this expression or declaration.
32const std::size_t float_count = sizeof(expected) / sizeof(expected[0]); // Set float count from this expression.
33const std::size_t bit_count = sizeof(expected_bits) / sizeof(expected_bits[0]); // Set bit count from this expression.
34
35void check(const shdr::buffer<float>& results, // Declare check with the parameters continued below.
36 const shdr::buffer<unsigned>& bits, // Declare bits for the following calculation.
37 const std::string& label) { // Declare label for the following calculation.
38 for (std::size_t i = 0; i < float_count; ++i) // Iterate over i for this calculation.
39 shdr_examples::require_close( // Check the computed value against the independent reference.
40 results.data()[i], expected[i], label + " float[" + std::to_string(i) + "]", 0.0002f); // Apply data to these arguments.
41 for (std::size_t i = 0; i < bit_count; ++i) // Iterate over i for this calculation.
42 if (bits.data()[i] != expected_bits[i]) // Check this condition before entering the following branch.
43 throw std::runtime_error(label + " bits[" + std::to_string(i) + "]: expected " + // Report bits[.
44 std::to_string(expected_bits[i]) + ", received " + // Apply to string to these arguments.
45 std::to_string(bits.data()[i])); // Apply to string to these arguments.
46} // End this block.
47} // namespace
48
49int main(int argc, char** argv) { // Run this example and validate its results.
50 try { // Run the operation while retaining the error handling below.
51 shdr_examples::runner runner(argc, argv); // Construct runner with these initial values.
52 shdr::buffer<float> results(float_count); // Construct results with these initial values.
53 shdr::buffer<unsigned> bits(bit_count); // Construct bits with these initial values.
54 std::unique_ptr<shdr::kernel> shader = shdr::make_kernel("math_kernel"); // Create the linked math kernel instance.
55 shader->bind("results", results); // Connect this shader port to its application resource.
56 shader->bind("bits", bits); // Connect this shader port to its application resource.
57 shader->set<shdr::glsl::vec2>("controls", shdr::glsl::vec2(1, -1)); // Supply this shader uniform with its typed application value.
58 shdr::pipeline pipeline; // Declare pipeline for the following calculation.
59 pipeline += shdr::dispatch(*shader, shdr::extent(1)); // Add a shader dispatch with the required workgroup counts.
60 pipeline.run(); // Execute the configured pipeline on the requested backend.
61 check(results, bits, "CPU math"); // Apply check to these arguments.
62 const shdr::buffer<float>& host_results = results; // Use a constant buffer view so GPU writes synchronize before host reads.
63 const shdr::buffer<unsigned>& host_bits = bits; // Use a constant buffer view so GPU writes synchronize before host reads.
64 const std::vector<float> cpu(host_results.data(), host_results.data() + float_count); // Construct cpu with these initial values.
65 const std::vector<unsigned> cpu_bits(host_bits.data(), host_bits.data() + bit_count); // Construct cpu bits with these initial values.
66 if (runner.gpu()) { // Check this condition before entering the following branch.
67 runner.run(pipeline); // Execute the configured pipeline on the requested backend.
68 check(results, bits, "GPU math"); // Apply check to these arguments.
69 for (std::size_t i = 0; i < float_count; ++i) // Iterate over i for this calculation.
70 shdr_examples::require_close( // Check the computed value against the independent reference.
71 host_results.data()[i], cpu[i], "CPU/GPU math parity", 0.0002f); // Apply data to these arguments.
72 for (std::size_t i = 0; i < bit_count; ++i) // Iterate over i for this calculation.
73 if (host_bits.data()[i] != cpu_bits[i]) // Check this condition before entering the following branch.
74 throw std::runtime_error("CPU/GPU bit operation parity"); // Report CPU/GPU bit operation parity.
75 } // End this block.
76 std::cout << "Native math shader " << (runner.gpu() ? "CPU/GPU" : "CPU") // Write this part of the example result or diagnostic.
77 << " checks passed\n"; // Write this part of the example result or diagnostic.
78 return 0; // Report successful completion.
79#ifdef SHDR_HAVE_EGL // Enable this branch when its feature macro is defined.
80 } catch (const shdr_examples::context_unavailable& e) { // Report the exception from the preceding operation.
81 std::cerr << "SKIP: " << e.what() << '\n'; // Write this part of the example result or diagnostic.
82 return 77; // Report an unavailable optional GPU backend.
83#endif // Finish this conditional compilation branch.
84 } catch (const std::exception& e) { // Report the exception from the preceding operation.
85 std::cerr << e.what() << '\n'; // Write this part of the example result or diagnostic.
86 return 1; // Report a failed check or operation.
87 } // End this block.
88} // End this block.