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.