// { dg-additional-options -std=c++20 } // { dg-output-file target-std__valarray-1.output } #include #include #include /*TODO Work around PR118484 "ICE during IPA pass: cp, segfault in determine_versionability ipa-cp.cc:467". We can't: #pragma omp declare target(std::basic_streambuf>::basic_streambuf) ... because: error: overloaded function name ‘std::basic_streambuf::__ct ’ in clause ‘enter’ Therefore, use dummy classes in '#pragma omp declare target': */ #pragma omp declare target // For 'std::basic_streambuf >::basic_streambuf': class dummy_basic_streambuf__char : public std::basic_streambuf { public: dummy_basic_streambuf__char() {} }; // For 'std::basic_ios >::basic_ios()': class dummy_basic_ios__char : public std::basic_ios { public: dummy_basic_ios__char() {} }; #pragma omp end declare target int main() { // Due to PR120021 "Offloading vs. C++ 'std::initializer_list'", we can't construct these on the device. std::initializer_list v1_i = {10, 20, 30, 40, 50}; const int *v1_i_data = std::data(v1_i); size_t v1_i_size = v1_i.size(); std::initializer_list v2_i = {5, 4, 3, 2, 1}; const int *v2_i_data = std::data(v2_i); size_t v2_i_size = v2_i.size(); std::initializer_list shiftData_i = {1, 2, 3, 4, 5}; const int *shiftData_i_data = std::data(shiftData_i); size_t shiftData_i_size = shiftData_i.size(); #pragma omp target \ defaultmap(none) \ map(to: v1_i_data[ :v1_i_size], v1_i_size, \ v2_i_data[ :v2_i_size], v2_i_size, \ shiftData_i_data[ :shiftData_i_size], shiftData_i_size) { /* Manually set up a buffer we can stream into, similar to 'cout << [...]', and print it at the end of region. */ std::stringbuf out_b; std::ostream out(&out_b); std::valarray v1(v1_i_data, v1_i_size); out << "\nv1:"; for (auto val : v1) out << " " << val; std::valarray v2(v2_i_data, v2_i_size); out << "\nv2:"; for (auto val : v2) out << " " << val; std::valarray sum = v1 + v2; out << "\nv1 + v2:"; for (auto val : sum) out << " " << val; std::valarray diff = v1 - v2; out << "\nv1 - v2:"; for (auto val : diff) out << " " << val; std::valarray product = v1 * v2; out << "\nv1 * v2:"; for (auto val : product) out << " " << val; std::valarray quotient = v1 / v2; out << "\nv1 / v2:"; for (auto val : quotient) out << " " << val; std::valarray squares = pow(v1, 2); out << "\npow(v1, 2):"; for (auto val : squares) out << " " << val; std::valarray sinhs = sinh(v2); out << "\nsinh(v2):"; for (auto val : sinhs) out << " " << val; std::valarray logs = log(v1 * v2); out << "\nlog(v1 * v2):"; for (auto val : logs) out << " " << val; std::valarray data(12); for (size_t i = 0; i < data.size(); ++i) data[i] = i; out << "\nOriginal array:"; for (auto val : data) out << " " << val; std::slice slice1(2, 5, 1); std::valarray sliced1 = data[slice1]; out << "\nSlice(2, 5, 1):"; for (auto val : sliced1) out << " " << val; std::slice slice2(1, 4, 3); std::valarray sliced2 = data[slice2]; out << "\nSlice(1, 4, 3):"; for (auto val : sliced2) out << " " << val; data[slice1] = 99; out << "\nArray after slice modification:"; for (auto val : data) out << " " << val; std::valarray mask = (v1 > 20); out << "\nElements of v1 > 20:"; for (size_t i = 0; i < v1.size(); ++i) { if (mask[i]) out << " " << v1[i]; } std::valarray masked = v1[mask]; out << "\nMasked array:"; for (auto val : masked) out << " " << val; std::valarray shiftData(shiftData_i_data, shiftData_i_size); out << "\nOriginal shiftData:"; for (auto val : shiftData) out << " " << val; std::valarray shifted = shiftData.shift(2); out << "\nshift(2):"; for (auto val : shifted) out << " " << val; std::valarray cshifted = shiftData.cshift(-1); out << "\ncshift(-1):"; for (auto val : cshifted) out << " " << val; out << "\nSum(v1): " << v1.sum(); out << "\nMin(v1): " << v1.min(); out << "\nMax(v1): " << v1.max(); out << "\n"; /* Terminate with a NUL. Otherwise, we'd have to use: __builtin_printf("%.*s", (int) out_b_sv.size(), out_b_sv.data()); ... which nvptx 'printf', as implemented via PTX 'vprintf', doesn't support (TODO). */ out << '\0'; std::string_view out_b_sv = out_b.view(); __builtin_printf("%s", out_b_sv.data()); } return 0; }