// Copyright (c) 2020-2025 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #include #include #include #include #include #include #include "include/host_device.h" // compute minimum and maximum values in a single reduction // minmax_pair stores the minimum and maximum // values that have been encountered so far template struct minmax_pair { T min_val; T max_val; }; // minmax_unary_op is a functor that takes in a value x and // returns a minmax_pair whose minimum and maximum values // are initialized to x. template struct minmax_unary_op { __host__ __device__ minmax_pair operator()(const T& x) const { minmax_pair result; result.min_val = x; result.max_val = x; return result; } }; // minmax_binary_op is a functor that accepts two minmax_pair // structs and returns a new minmax_pair whose minimum and // maximum values are the min() and max() respectively of // the minimums and maximums of the input pairs template struct minmax_binary_op { __host__ __device__ minmax_pair operator()(const minmax_pair& x, const minmax_pair& y) const { minmax_pair result; result.min_val = thrust::min(x.min_val, y.min_val); result.max_val = thrust::max(x.max_val, y.max_val); return result; } }; int main(void) { // input size size_t N = 10; // initialize random number generator thrust::default_random_engine rng; thrust::uniform_int_distribution dist(10, 99); // initialize data on host thrust::device_vector data(N); for (size_t i = 0; i < data.size(); i++) { data[i] = dist(rng); } // setup arguments minmax_unary_op unary_op; minmax_binary_op binary_op; // initialize reduction with the first value minmax_pair init = unary_op(data[0]); // compute minimum and maximum values minmax_pair result = thrust::transform_reduce(data.begin(), data.end(), unary_op, init, binary_op); // print results std::cout << "[ "; for (size_t i = 0; i < N; i++) { std::cout << data[i] << " "; } std::cout << "]" << std::endl; std::cout << "minimum = " << result.min_val << std::endl; std::cout << "maximum = " << result.max_val << std::endl; return 0; }