/* Copyright (C) 2022-2024 Free Software Foundation, Inc. Copyright (C) 2022-2024 Advanced Micro Devices, Inc. All rights reserved. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #define CHECK(cmd) \ { \ hipError_t error = cmd; \ if (error != hipSuccess) { \ fprintf(stderr, "error: '%s'(%d) at %s:%d\n", \ hipGetErrorString(error), error, __FILE__, __LINE__); \ exit(EXIT_FAILURE); \ } \ } /* Define a set of types that will be returned from functions. */ struct Empty {}; template struct Custom { T data[N]; }; union Union { int as_int; char as_chars[4]; }; /* Structs (or unions) with flexible arrays are never returned by value. */ struct FlexibleArrayMember { int non_flexible; char flex[]; }; struct PackedWithBitField { int x : 7; int y : 7; int z : 7; }; /* A structure that is more than 8 bytes (otherwise it is returned as packed), which contains bitfields. */ struct NotPackedWithBitField { int foo[4]; unsigned int x : 4; unsigned int y : 4; unsigned int z : 7; char c1; char c2; char c3 : 8; char c4 : 8; char : 0; char c5 : 8; char c6 : 8; }; struct MixedSmallStruct { float a; short b[2]; }; struct OnlyStatic { __device__ static int something; }; __device__ int OnlyStatic::something = 42; struct WithStaticFields { int a[2]; OnlyStatic sub; float b; __device__ static int c; double d; }; __device__ int WithStaticFields::c = 12; __device__ static Empty returnEmpty () { return {}; } template __device__ static Custom returnSized () { Custom ret; static_assert (sizeof (ret) == N, "Invalid size"); for (int i = 0; i < N; ++i) ret.data[i] = 'a' + static_cast (threadIdx.x); return ret; } template __device__ static Custom returnCustomWithUnion () { Custom ret; for (size_t i = 0; i < N; i++) ret.data[i].as_int = 0x61616161; return ret; } __device__ static FlexibleArrayMember returnFlexibleArrayMember () { return { .non_flexible = static_cast (threadIdx.x) }; } __device__ static NotPackedWithBitField returnNotPackedWithBitField () { const int val = static_cast (threadIdx.x); return { .foo = {val, val + 1, val + 2, val + 3}, .x = static_cast (val + 4), .y = static_cast (val + 5), .z = static_cast (val + 6), .c1 = 'a', .c2 = 'b', .c3 = 'c', .c4 = 'd', .c5 = 'e', .c6 = 'f', }; } __device__ static PackedWithBitField returnPackedWithBitField () { const int val = static_cast (threadIdx.x); return { .x = static_cast (val), .y = static_cast (val + 1), .z = static_cast (val + 2) }; } __device__ static const Custom * returnPtr () { static Custom vv { .data = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'} }; return &vv; } __device__ static int * returnPtr2 (int *a) { return a; } __device__ static const Custom & returnRef () { static Custom vv { .data = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'} }; return vv; }; __device__ static int & returnRef2 (int &a) { return a; } __device__ static WithStaticFields returnWithStatic () { OnlyStatic::something = 12; WithStaticFields::c = 42; return { .a = { 8, 16 }, .b = 3.14, .d = 1.60218e-19 }; } __device__ static OnlyStatic returnEmptyWithStatic () { OnlyStatic::something = 56; return {}; } __device__ static __attribute__((noinline)) MixedSmallStruct returnMixedSmallSruct () { MixedSmallStruct var; var.b[0] = 4; var.b[1] = 7; var.a = 3.14; return var; } __device__ int someGlobal = 42; __global__ void kernel () { returnEmpty (); returnEmptyWithStatic (); returnMixedSmallSruct (); returnSized<1> (); returnSized<2> (); returnSized<4> (); returnSized<8> (); returnSized<9> (); returnSized<16> (); returnSized<32> (); returnSized<33> (); returnSized<64> (); returnSized<128> (); returnCustomWithUnion<2> (); returnCustomWithUnion<4> (); returnCustomWithUnion<6> (); returnCustomWithUnion<8> (); returnCustomWithUnion<16> (); returnCustomWithUnion<20> (); returnFlexibleArrayMember (); returnPackedWithBitField (); returnNotPackedWithBitField (); int myId = threadIdx.x + threadIdx.y * blockDim.x + threadIdx.z * blockDim.x * blockDim.y; returnPtr (); returnPtr2 (&myId); returnPtr2 (&someGlobal); returnRef (); returnRef2 (myId); returnRef2 (someGlobal); returnWithStatic (); returnWithStatic (); } int main () { hipDeviceProp_t prop; CHECK (hipGetDeviceProperties (&prop, 0)); hipLaunchKernelGGL (kernel, dim3 (1), dim3 (prop.warpSize), 0, 0); CHECK (hipDeviceSynchronize ()); }