/*
 * Copyright 1993-2007 NVIDIA Corporation.  All rights reserved.
 *
 * NOTICE TO USER:
 *
 * This source code is subject to NVIDIA ownership rights under U.S. and
 * international Copyright laws.  Users and possessors of this source code
 * are hereby granted a nonexclusive, royalty-free license to use this code
 * in individual and commercial software.
 *
 * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE
 * CODE FOR ANY PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR
 * IMPLIED WARRANTY OF ANY KIND.  NVIDIA DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
 * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
 * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 * OF USE, DATA OR PROFITS,  WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION,  ARISING OUT OF OR IN CONNECTION WITH THE USE
 * OR PERFORMANCE OF THIS SOURCE CODE.
 *
 * U.S. Government End Users.   This source code is a "commercial item" as
 * that term is defined at  48 C.F.R. 2.101 (OCT 1995), consisting  of
 * "commercial computer  software"  and "commercial computer software
 * documentation" as such terms are  used in 48 C.F.R. 12.212 (SEPT 1995)
 * and is provided to the U.S. Government only as a commercial end item.
 * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through
 * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the
 * source code with only those rights set forth herein.
 *
 * Any use of this source code in individual and commercial software must
 * include, in the user documentation and internal comments to the code,
 * the above Disclaimer and U.S. Government End Users Notice.
 */

/* This sample queries the properties of the CUDA devices present in the system. */

// includes, system
#include <stdlib.h>
#include <stdio.h>
#include <string.h>


inline int _ConvertSMVer2Cores(int major, int minor)
{
    // Defines for GPU Architecture types (using the SM version to determine the # of cores per SM
    typedef struct
    {
        int SM; // 0xMm (hexidecimal notation), M = SM Major version, and m = SM minor version
        int Cores;
    } sSMtoCores;

    sSMtoCores nGpuArchCoresPerSM[] =
    {
        { 0x20, 32 }, // Fermi Generation (SM 2.0) GF100 class
        { 0x21, 48 }, // Fermi Generation (SM 2.1) GF10x class
        { 0x30, 192}, // Kepler Generation (SM 3.0) GK10x class
        { 0x32, 192}, // Kepler Generation (SM 3.2) GK10x class
        { 0x35, 192}, // Kepler Generation (SM 3.5) GK11x class
        { 0x37, 192}, // Kepler Generation (SM 3.7) GK21x class
        { 0x50, 128}, // Maxwell Generation (SM 5.0) GM10x class
        { 0x52, 128}, // Maxwell Generation (SM 5.2) GM20x class
        { 0x53, 128}, // Maxwell Generation (SM 5.3) GM20x class
        { 0x60, 64 }, // Pascal Generation (SM 6.0) GP100 class
        { 0x61, 128}, // Pascal Generation (SM 6.1) GP10x class
        { 0x62, 128}, // Pascal Generation (SM 6.2) GP10x class
        {   -1, -1 }
    };

    int index = 0;

    while (nGpuArchCoresPerSM[index].SM != -1)
    {
        if (nGpuArchCoresPerSM[index].SM == ((major << 4) + minor))
        {
            return nGpuArchCoresPerSM[index].Cores;
        }

        index++;
    }

    // If we don't find the values, we default use the previous one to run properly
    printf("MapSMtoCores for SM %d.%d is undefined.  Default to use %d Cores/SM\n", major, minor, nGpuArchCoresPerSM[index-1].Cores);
    return nGpuArchCoresPerSM[index-1].Cores;
}







////////////////////////////////////////////////////////////////////////////////
// Program main
////////////////////////////////////////////////////////////////////////////////
int
main( int argc, char** argv)
{
    int deviceCount;
    cudaGetDeviceCount(&deviceCount);
    if (deviceCount == 0)
        printf("There is no device supporting CUDA\n");
    int dev;
    for (dev = 0; dev < deviceCount; ++dev) {
        cudaDeviceProp deviceProp;
        cudaGetDeviceProperties(&deviceProp, dev);
        if (dev == 0) {
            if (deviceProp.major == 9999 && deviceProp.minor == 9999)
                printf("There is no device supporting CUDA.\n");
            else if (deviceCount == 1)
                printf("There is 1 device supporting CUDA\n");
            else
                printf("There are %d devices supporting CUDA\n", deviceCount);
        }
        printf("\nDevice %d: \"%s\"\n", dev, deviceProp.name);
        printf("  Major revision number:                         %d\n",
               deviceProp.major);
        printf("  Minor revision number:                         %d\n",
               deviceProp.minor);
        printf("  Total amount of global memory:                 %zd bytes\n",
               deviceProp.totalGlobalMem);
    #if CUDART_VERSION >= 2000
        printf("  Number of multiprocessors:                     %d\n",
               deviceProp.multiProcessorCount);
        printf("  CUDA Cores/MP:                                 %d\n",
               _ConvertSMVer2Cores(deviceProp.major, deviceProp.minor));
        printf("  Total CUDA Cores                               %d\n",
               _ConvertSMVer2Cores(deviceProp.major, deviceProp.minor) * deviceProp.multiProcessorCount);
    #endif
        printf("  Total amount of constant memory:               %zd bytes\n",
               deviceProp.totalConstMem);
        printf("  Total amount of shared memory per block:       %zd bytes\n",
               deviceProp.sharedMemPerBlock);
        printf("  Total number of registers available per block: %d\n",
               deviceProp.regsPerBlock);
        printf("  Warp size:                                     %d\n",
               deviceProp.warpSize);
        printf("  Maximum number of threads per block:           %d\n",
               deviceProp.maxThreadsPerBlock);
        printf("  Maximum sizes of each dimension of a block:    %d x %d x %d\n",
               deviceProp.maxThreadsDim[0],
               deviceProp.maxThreadsDim[1],
               deviceProp.maxThreadsDim[2]);
        printf("  Maximum sizes of each dimension of a grid:     %d x %d x %d\n",
               deviceProp.maxGridSize[0],
               deviceProp.maxGridSize[1],
               deviceProp.maxGridSize[2]);
        printf("  Maximum memory pitch:                          %zd bytes\n",
               deviceProp.memPitch);
        printf("  Texture alignment:                             %zd bytes\n",
               deviceProp.textureAlignment);
        printf("  Clock rate:                                    %.2f GHz\n",
               deviceProp.clockRate * 1e-6f);
        printf("  Memory Clock rate:                             %.2f GHz\n",
               deviceProp.memoryClockRate * 1e-6f);
        printf("  Memory Bus Width:                              %d bits\n",
               deviceProp.memoryBusWidth);
        printf("  Number of asynchronous engines:                %d\n",
               deviceProp.asyncEngineCount);
        printf("  It can execute multiple kernels concurrently:  %s\n",
               deviceProp.concurrentKernels ? "Yes" : "No");
    #if CUDART_VERSION >= 2000
        printf("  Concurrent copy and execution:                 %s\n",
               deviceProp.deviceOverlap ? "Yes" : "No");
    #endif
    }
    printf("\nTEST PASSED\n");
}

	.file	"tmpxft_00385778_00000000-6_dev_properties.cudafe1.cpp"
	.text
#APP

#NO_APP
	.type	_ZL26__cudaUnregisterBinaryUtilv, @function
_ZL26__cudaUnregisterBinaryUtilv:
.LFB2031:
	.cfi_startproc
	endbr64
	movq	_ZL20__cudaFatCubinHandle(%rip), %rdi
	jmp	__cudaUnregisterFatBinary@PLT
	.cfi_endproc
.LFE2031:
	.size	_ZL26__cudaUnregisterBinaryUtilv, .-_ZL26__cudaUnregisterBinaryUtilv
	.section	.rodata._Z19_ConvertSMVer2Coresii.str1.1,"aMS",@progbits,1
.LC1:
	.string	"MapSMtoCores for SM %d.%d is undefined.  Default to use %d Cores/SM\n"
	.section	.rodata
	.align 32
.LC0:
	.long	32
	.long	32
	.long	33
	.long	48
	.long	48
	.long	192
	.long	50
	.long	192
	.long	53
	.long	192
	.long	55
	.long	192
	.long	80
	.long	128
	.long	82
	.long	128
	.long	83
	.long	128
	.long	96
	.long	64
	.long	97
	.long	128
	.long	98
	.long	128
	.long	-1
	.long	-1
	.section	.text._Z19_ConvertSMVer2Coresii,"axG",@progbits,_Z19_ConvertSMVer2Coresii,comdat
	.weak	_Z19_ConvertSMVer2Coresii
	.type	_Z19_ConvertSMVer2Coresii, @function
_Z19_ConvertSMVer2Coresii:
.LFB2027:
	.cfi_startproc
	endbr64
	pushq	%rbx
	.cfi_def_cfa_offset 16
	.cfi_offset 3, -16
	movl	%edi, %edx
	movl	%esi, %r9d
	movl	$26, %ecx
	leaq	.LC0(%rip), %rsi
	subq	$112, %rsp
	.cfi_def_cfa_offset 128
	movq	%fs:40, %rax
	movq	%rax, 104(%rsp)
	xorl	%eax, %eax
	movq	%rsp, %rdi
	movq	%rsp, %r8
	rep movsl
	movl	%edx, %esi
	sall	$4, %esi
	addl	%r9d, %esi
.L3:
	movl	(%r8,%rax,8), %edi
	movslq	%eax, %rcx
	cmpl	$-1, %edi
	je	.L10
	incq	%rax
	cmpl	%edi, %esi
	jne	.L3
	movl	4(%rsp,%rcx,8), %ebx
	jmp	.L2
.L10:
	decl	%eax
	movl	%r9d, %ecx
	movl	$2, %edi
	cltq
	leaq	.LC1(%rip), %rsi
	movl	4(%rsp,%rax,8), %ebx
	xorl	%eax, %eax
	movl	%ebx, %r8d
	call	__printf_chk@PLT
.L2:
	movq	104(%rsp), %rax
	subq	%fs:40, %rax
	je	.L6
	call	__stack_chk_fail@PLT
.L6:
	addq	$112, %rsp
	.cfi_def_cfa_offset 16
	movl	%ebx, %eax
	popq	%rbx
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2027:
	.size	_Z19_ConvertSMVer2Coresii, .-_Z19_ConvertSMVer2Coresii
	.section	.rodata.str1.1,"aMS",@progbits,1
.LC2:
	.string	"Yes"
.LC3:
	.string	"No"
.LC4:
	.string	"There is no device supporting CUDA\n"
.LC5:
	.string	"There is no device supporting CUDA.\n"
.LC6:
	.string	"There is 1 device supporting CUDA\n"
.LC7:
	.string	"There are %d devices supporting CUDA\n"
.LC8:
	.string	"\nDevice %d: \"%s\"\n"
.LC9:
	.string	"  Major revision number:                         %d\n"
.LC10:
	.string	"  Minor revision number:                         %d\n"
.LC11:
	.string	"  Total amount of global memory:                 %zd bytes\n"
.LC12:
	.string	"  Number of multiprocessors:                     %d\n"
.LC13:
	.string	"  CUDA Cores/MP:                                 %d\n"
.LC14:
	.string	"  Total CUDA Cores                               %d\n"
.LC15:
	.string	"  Total amount of constant memory:               %zd bytes\n"
.LC16:
	.string	"  Total amount of shared memory per block:       %zd bytes\n"
.LC17:
	.string	"  Total number of registers available per block: %d\n"
.LC18:
	.string	"  Warp size:                                     %d\n"
.LC19:
	.string	"  Maximum number of threads per block:           %d\n"
.LC20:
	.string	"  Maximum sizes of each dimension of a block:    %d x %d x %d\n"
.LC21:
	.string	"  Maximum sizes of each dimension of a grid:     %d x %d x %d\n"
.LC22:
	.string	"  Maximum memory pitch:                          %zd bytes\n"
.LC23:
	.string	"  Texture alignment:                             %zd bytes\n"
.LC25:
	.string	"  Clock rate:                                    %.2f GHz\n"
.LC26:
	.string	"  Memory Clock rate:                             %.2f GHz\n"
.LC27:
	.string	"  Memory Bus Width:                              %d bits\n"
.LC28:
	.string	"  Number of asynchronous engines:                %d\n"
.LC29:
	.string	"  It can execute multiple kernels concurrently:  %s\n"
.LC30:
	.string	"  Concurrent copy and execution:                 %s\n"
.LC31:
	.string	"\nTEST PASSED\n"
	.section	.text.startup,"ax",@progbits
	.globl	main
	.type	main, @function
main:
.LFB2028:
	.cfi_startproc
	endbr64
	pushq	%r13
	.cfi_def_cfa_offset 16
	.cfi_offset 13, -16
	pushq	%r12
	.cfi_def_cfa_offset 24
	.cfi_offset 12, -24
	pushq	%rbp
	.cfi_def_cfa_offset 32
	.cfi_offset 6, -32
	pushq	%rbx
	.cfi_def_cfa_offset 40
	.cfi_offset 3, -40
	subq	$1064, %rsp
	.cfi_def_cfa_offset 1104
	movq	%fs:40, %rax
	movq	%rax, 1048(%rsp)
	xorl	%eax, %eax
	leaq	12(%rsp), %rdi
	call	cudaGetDeviceCount@PLT
	cmpl	$0, 12(%rsp)
	jne	.L12
	leaq	.LC4(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L12:
	movabsq	$42945378002703, %rbp
	xorl	%ebx, %ebx
.L13:
	cmpl	%ebx, 12(%rsp)
	jle	.L25
	leaq	16(%rsp), %r12
	movl	%ebx, %esi
	movq	%r12, %rdi
	call	cudaGetDeviceProperties_v2@PLT
	testl	%ebx, %ebx
	jne	.L14
	leaq	.LC5(%rip), %rsi
	cmpq	%rbp, 376(%rsp)
	je	.L24
	movl	12(%rsp), %edx
	cmpl	$1, %edx
	jne	.L16
	leaq	.LC6(%rip), %rsi
.L24:
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	jmp	.L14
.L16:
	leaq	.LC7(%rip), %rsi
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
.L14:
	movq	%r12, %rcx
	movl	%ebx, %edx
	leaq	.LC8(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	leaq	.LC2(%rip), %r13
	leaq	.LC3(%rip), %r12
	call	__printf_chk@PLT
	movl	376(%rsp), %edx
	leaq	.LC9(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
	movl	380(%rsp), %edx
	leaq	.LC10(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
	movq	304(%rsp), %rdx
	leaq	.LC11(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
	movl	404(%rsp), %edx
	leaq	.LC12(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
	movl	380(%rsp), %esi
	movl	376(%rsp), %edi
	call	_Z19_ConvertSMVer2Coresii
	leaq	.LC13(%rip), %rsi
	movl	$2, %edi
	movl	%eax, %edx
	xorl	%eax, %eax
	call	__printf_chk@PLT
	movl	380(%rsp), %esi
	movl	376(%rsp), %edi
	call	_Z19_ConvertSMVer2Coresii
	imull	404(%rsp), %eax
	movl	$2, %edi
	leaq	.LC14(%rip), %rsi
	movl	%eax, %edx
	xorl	%eax, %eax
	call	__printf_chk@PLT
	movq	368(%rsp), %rdx
	leaq	.LC15(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
	movq	312(%rsp), %rdx
	leaq	.LC16(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
	movl	320(%rsp), %edx
	leaq	.LC17(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
	movl	324(%rsp), %edx
	leaq	.LC18(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
	movl	336(%rsp), %edx
	leaq	.LC19(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
	movl	348(%rsp), %r8d
	xorl	%eax, %eax
	movl	344(%rsp), %ecx
	movl	340(%rsp), %edx
	leaq	.LC20(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
	movl	360(%rsp), %r8d
	xorl	%eax, %eax
	movl	356(%rsp), %ecx
	movl	352(%rsp), %edx
	leaq	.LC21(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
	movq	328(%rsp), %rdx
	leaq	.LC22(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
	movq	384(%rsp), %rdx
	leaq	.LC23(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
	leaq	.LC25(%rip), %rsi
	movl	$2, %edi
	movb	$1, %al
	cvtsi2ssl	364(%rsp), %xmm0
	mulss	.LC24(%rip), %xmm0
	cvtss2sd	%xmm0, %xmm0
	call	__printf_chk@PLT
	movl	$2, %edi
	movb	$1, %al
	cvtsi2ssl	624(%rsp), %xmm0
	leaq	.LC26(%rip), %rsi
	mulss	.LC24(%rip), %xmm0
	cvtss2sd	%xmm0, %xmm0
	call	__printf_chk@PLT
	movl	$2, %edi
	xorl	%eax, %eax
	movl	628(%rsp), %edx
	leaq	.LC27(%rip), %rsi
	call	__printf_chk@PLT
	movl	616(%rsp), %edx
	leaq	.LC28(%rip), %rsi
	xorl	%eax, %eax
	movl	$2, %edi
	call	__printf_chk@PLT
	cmpl	$0, 592(%rsp)
	movq	%r13, %rdx
	leaq	.LC29(%rip), %rsi
	cmove	%r12, %rdx
	movl	$2, %edi
	xorl	%eax, %eax
	call	__printf_chk@PLT
	cmpl	$0, 400(%rsp)
	movq	%r13, %rdx
	leaq	.LC30(%rip), %rsi
	cmove	%r12, %rdx
	movl	$2, %edi
	xorl	%eax, %eax
	incl	%ebx
	call	__printf_chk@PLT
	jmp	.L13
.L25:
	xorl	%eax, %eax
	leaq	.LC31(%rip), %rsi
	movl	$2, %edi
	call	__printf_chk@PLT
	movq	1048(%rsp), %rax
	subq	%fs:40, %rax
	je	.L20
	call	__stack_chk_fail@PLT
.L20:
	addq	$1064, %rsp
	.cfi_def_cfa_offset 40
	xorl	%eax, %eax
	popq	%rbx
	.cfi_def_cfa_offset 32
	popq	%rbp
	.cfi_def_cfa_offset 24
	popq	%r12
	.cfi_def_cfa_offset 16
	popq	%r13
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE2028:
	.size	main, .-main
	.type	_ZL24__sti____cudaRegisterAllv, @function
_ZL24__sti____cudaRegisterAllv:
.LFB2054:
	.cfi_startproc
	endbr64
	pushq	%rax
	.cfi_def_cfa_offset 16
	leaq	_ZL15__fatDeviceText(%rip), %rdi
	call	__cudaRegisterFatBinary@PLT
	movq	%rax, %rdi
	movq	%rax, _ZL20__cudaFatCubinHandle(%rip)
	call	__cudaRegisterFatBinaryEnd@PLT
	leaq	_ZL26__cudaUnregisterBinaryUtilv(%rip), %rdi
	popq	%rdx
	.cfi_def_cfa_offset 8
	jmp	atexit@PLT
	.cfi_endproc
.LFE2054:
	.size	_ZL24__sti____cudaRegisterAllv, .-_ZL24__sti____cudaRegisterAllv
	.section	.init_array,"aw"
	.align 8
	.quad	_ZL24__sti____cudaRegisterAllv
	.section	.nvFatBinSegment,"aw"
	.align 8
	.type	_ZL15__fatDeviceText, @object
	.size	_ZL15__fatDeviceText, 24
_ZL15__fatDeviceText:
	.long	1180844977
	.long	1
	.quad	fatbinData
	.quad	0
	.local	_ZL20__cudaFatCubinHandle
	.comm	_ZL20__cudaFatCubinHandle,8,8
	.section	.rodata.cst4,"aM",@progbits,4
	.align 4
.LC24:
	.long	897988541
	.ident	"GCC: (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0"
	.section	.note.GNU-stack,"",@progbits
	.section	.note.gnu.property,"a"
	.align 8
	.long	1f - 0f
	.long	4f - 1f
	.long	5
0:
	.string	"GNU"
1:
	.align 8
	.long	0xc0000002
	.long	3f - 2f
2:
	.long	0x3
3:
	.align 8
4:

/*
 * Copyright 1993-2007 NVIDIA Corporation.  All rights reserved.
 *
 * NOTICE TO USER:
 *
 * This source code is subject to NVIDIA ownership rights under U.S. and
 * international Copyright laws.  Users and possessors of this source code
 * are hereby granted a nonexclusive, royalty-free license to use this code
 * in individual and commercial software.
 *
 * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE
 * CODE FOR ANY PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR
 * IMPLIED WARRANTY OF ANY KIND.  NVIDIA DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
 * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
 * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 * OF USE, DATA OR PROFITS,  WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION,  ARISING OUT OF OR IN CONNECTION WITH THE USE
 * OR PERFORMANCE OF THIS SOURCE CODE.
 *
 * U.S. Government End Users.   This source code is a "commercial item" as
 * that term is defined at  48 C.F.R. 2.101 (OCT 1995), consisting  of
 * "commercial computer  software"  and "commercial computer software
 * documentation" as such terms are  used in 48 C.F.R. 12.212 (SEPT 1995)
 * and is provided to the U.S. Government only as a commercial end item.
 * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through
 * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the
 * source code with only those rights set forth herein.
 *
 * Any use of this source code in individual and commercial software must
 * include, in the user documentation and internal comments to the code,
 * the above Disclaimer and U.S. Government End Users Notice.
 */

/* This sample queries the properties of the CUDA devices present in the system. */

// includes, system

#include <hip/hip_runtime.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>


inline int _ConvertSMVer2Cores(int major, int minor)
{
    // Defines for GPU Architecture types (using the SM version to determine the # of cores per SM
    typedef struct
    {
        int SM; // 0xMm (hexidecimal notation), M = SM Major version, and m = SM minor version
        int Cores;
    } sSMtoCores;

    sSMtoCores nGpuArchCoresPerSM[] =
    {
        { 0x20, 32 }, // Fermi Generation (SM 2.0) GF100 class
        { 0x21, 48 }, // Fermi Generation (SM 2.1) GF10x class
        { 0x30, 192}, // Kepler Generation (SM 3.0) GK10x class
        { 0x32, 192}, // Kepler Generation (SM 3.2) GK10x class
        { 0x35, 192}, // Kepler Generation (SM 3.5) GK11x class
        { 0x37, 192}, // Kepler Generation (SM 3.7) GK21x class
        { 0x50, 128}, // Maxwell Generation (SM 5.0) GM10x class
        { 0x52, 128}, // Maxwell Generation (SM 5.2) GM20x class
        { 0x53, 128}, // Maxwell Generation (SM 5.3) GM20x class
        { 0x60, 64 }, // Pascal Generation (SM 6.0) GP100 class
        { 0x61, 128}, // Pascal Generation (SM 6.1) GP10x class
        { 0x62, 128}, // Pascal Generation (SM 6.2) GP10x class
        {   -1, -1 }
    };

    int index = 0;

    while (nGpuArchCoresPerSM[index].SM != -1)
    {
        if (nGpuArchCoresPerSM[index].SM == ((major << 4) + minor))
        {
            return nGpuArchCoresPerSM[index].Cores;
        }

        index++;
    }

    // If we don't find the values, we default use the previous one to run properly
    printf("MapSMtoCores for SM %d.%d is undefined.  Default to use %d Cores/SM\n", major, minor, nGpuArchCoresPerSM[index-1].Cores);
    return nGpuArchCoresPerSM[index-1].Cores;
}







////////////////////////////////////////////////////////////////////////////////
// Program main
////////////////////////////////////////////////////////////////////////////////
int
main( int argc, char** argv)
{
    int deviceCount;
    hipGetDeviceCount(&deviceCount);
    if (deviceCount == 0)
        printf("There is no device supporting CUDA\n");
    int dev;
    for (dev = 0; dev < deviceCount; ++dev) {
        hipDeviceProp_t deviceProp;
        hipGetDeviceProperties(&deviceProp, dev);
        if (dev == 0) {
            if (deviceProp.major == 9999 && deviceProp.minor == 9999)
                printf("There is no device supporting CUDA.\n");
            else if (deviceCount == 1)
                printf("There is 1 device supporting CUDA\n");
            else
                printf("There are %d devices supporting CUDA\n", deviceCount);
        }
        printf("\nDevice %d: \"%s\"\n", dev, deviceProp.name);
        printf("  Major revision number:                         %d\n",
               deviceProp.major);
        printf("  Minor revision number:                         %d\n",
               deviceProp.minor);
        printf("  Total amount of global memory:                 %zd bytes\n",
               deviceProp.totalGlobalMem);
    #if CUDART_VERSION >= 2000
        printf("  Number of multiprocessors:                     %d\n",
               deviceProp.multiProcessorCount);
        printf("  CUDA Cores/MP:                                 %d\n",
               _ConvertSMVer2Cores(deviceProp.major, deviceProp.minor));
        printf("  Total CUDA Cores                               %d\n",
               _ConvertSMVer2Cores(deviceProp.major, deviceProp.minor) * deviceProp.multiProcessorCount);
    #endif
        printf("  Total amount of constant memory:               %zd bytes\n",
               deviceProp.totalConstMem);
        printf("  Total amount of shared memory per block:       %zd bytes\n",
               deviceProp.sharedMemPerBlock);
        printf("  Total number of registers available per block: %d\n",
               deviceProp.regsPerBlock);
        printf("  Warp size:                                     %d\n",
               deviceProp.warpSize);
        printf("  Maximum number of threads per block:           %d\n",
               deviceProp.maxThreadsPerBlock);
        printf("  Maximum sizes of each dimension of a block:    %d x %d x %d\n",
               deviceProp.maxThreadsDim[0],
               deviceProp.maxThreadsDim[1],
               deviceProp.maxThreadsDim[2]);
        printf("  Maximum sizes of each dimension of a grid:     %d x %d x %d\n",
               deviceProp.maxGridSize[0],
               deviceProp.maxGridSize[1],
               deviceProp.maxGridSize[2]);
        printf("  Maximum memory pitch:                          %zd bytes\n",
               deviceProp.memPitch);
        printf("  Texture alignment:                             %zd bytes\n",
               deviceProp.textureAlignment);
        printf("  Clock rate:                                    %.2f GHz\n",
               deviceProp.clockRate * 1e-6f);
        printf("  Memory Clock rate:                             %.2f GHz\n",
               deviceProp.memoryClockRate * 1e-6f);
        printf("  Memory Bus Width:                              %d bits\n",
               deviceProp.memoryBusWidth);
        printf("  Number of asynchronous engines:                %d\n",
               deviceProp.asyncEngineCount);
        printf("  It can execute multiple kernels concurrently:  %s\n",
               deviceProp.concurrentKernels ? "Yes" : "No");
    #if CUDART_VERSION >= 2000
        printf("  Concurrent copy and execution:                 %s\n",
               deviceProp.deviceOverlap ? "Yes" : "No");
    #endif
    }
    printf("\nTEST PASSED\n");
}

	.text
	.file	"dev_properties.hip"
	.section	.rodata.cst4,"aM",@progbits,4
	.p2align	2, 0x0                          # -- Begin function main
.LCPI0_0:
	.long	0x358637bd                      # float 9.99999997E-7
	.text
	.globl	main
	.type	main,@function
main:                                   # @main
	.cfi_startproc
# %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	pushq	%r14
	.cfi_def_cfa_offset 24
	pushq	%rbx
	.cfi_def_cfa_offset 32
	subq	$1488, %rsp                     # imm = 0x5D0
	.cfi_def_cfa_offset 1520
	.cfi_offset %rbx, -32
	.cfi_offset %r14, -24
	.cfi_offset %rbp, -16
	leaq	12(%rsp), %rbx
	movq	%rbx, %rdi
	callq	hipGetDeviceCount
	movl	(%rbx), %eax
	testl	%eax, %eax
	jne	.LBB0_2
# %bb.1:
	movl	$.Lstr, %edi
	callq	puts@PLT
	movl	12(%rsp), %eax
.LBB0_2:
	testl	%eax, %eax
	jle	.LBB0_13
# %bb.3:                                # %.lr.ph
	leaq	16(%rsp), %rbx
	movl	$.L.str.23, %r14d
	xorl	%ebp, %ebp
.LBB0_4:                                # =>This Inner Loop Header: Depth=1
	movq	%rbx, %rdi
	movl	%ebp, %esi
	callq	hipGetDevicePropertiesR0600
	testl	%ebp, %ebp
	jne	.LBB0_12
# %bb.5:                                #   in Loop: Header=BB0_4 Depth=1
	cmpl	$9999, 376(%rsp)                # imm = 0x270F
	jne	.LBB0_9
# %bb.6:                                #   in Loop: Header=BB0_4 Depth=1
	cmpl	$9999, 380(%rsp)                # imm = 0x270F
	jne	.LBB0_9
# %bb.7:                                #   in Loop: Header=BB0_4 Depth=1
	movl	$.Lstr.3, %edi
	jmp	.LBB0_8
.LBB0_9:                                #   in Loop: Header=BB0_4 Depth=1
	movl	12(%rsp), %esi
	cmpl	$1, %esi
	jne	.LBB0_11
# %bb.10:                               #   in Loop: Header=BB0_4 Depth=1
	movl	$.Lstr.2, %edi
.LBB0_8:                                #   in Loop: Header=BB0_4 Depth=1
	callq	puts@PLT
	jmp	.LBB0_12
.LBB0_11:                               #   in Loop: Header=BB0_4 Depth=1
	movl	$.L.str.3, %edi
	xorl	%eax, %eax
	callq	printf
.LBB0_12:                               #   in Loop: Header=BB0_4 Depth=1
	movl	$.L.str.4, %edi
	movl	%ebp, %esi
	movq	%rbx, %rdx
	xorl	%eax, %eax
	callq	printf
	movl	376(%rsp), %esi
	movl	$.L.str.5, %edi
	xorl	%eax, %eax
	callq	printf
	movl	380(%rsp), %esi
	movl	$.L.str.6, %edi
	xorl	%eax, %eax
	callq	printf
	movq	304(%rsp), %rsi
	movl	$.L.str.7, %edi
	xorl	%eax, %eax
	callq	printf
	movq	368(%rsp), %rsi
	movl	$.L.str.8, %edi
	xorl	%eax, %eax
	callq	printf
	movq	312(%rsp), %rsi
	movl	$.L.str.9, %edi
	xorl	%eax, %eax
	callq	printf
	movl	320(%rsp), %esi
	movl	$.L.str.10, %edi
	xorl	%eax, %eax
	callq	printf
	movl	324(%rsp), %esi
	movl	$.L.str.11, %edi
	xorl	%eax, %eax
	callq	printf
	movl	336(%rsp), %esi
	movl	$.L.str.12, %edi
	xorl	%eax, %eax
	callq	printf
	movl	340(%rsp), %esi
	movl	344(%rsp), %edx
	movl	348(%rsp), %ecx
	movl	$.L.str.13, %edi
	xorl	%eax, %eax
	callq	printf
	movl	352(%rsp), %esi
	movl	356(%rsp), %edx
	movl	360(%rsp), %ecx
	movl	$.L.str.14, %edi
	xorl	%eax, %eax
	callq	printf
	movq	328(%rsp), %rsi
	movl	$.L.str.15, %edi
	xorl	%eax, %eax
	callq	printf
	movq	384(%rsp), %rsi
	movl	$.L.str.16, %edi
	xorl	%eax, %eax
	callq	printf
	cvtsi2ssl	364(%rsp), %xmm0
	movss	.LCPI0_0(%rip), %xmm1           # xmm1 = mem[0],zero,zero,zero
	mulss	%xmm1, %xmm0
	cvtss2sd	%xmm0, %xmm0
	movl	$.L.str.17, %edi
	movb	$1, %al
	callq	printf
	xorps	%xmm0, %xmm0
	cvtsi2ssl	624(%rsp), %xmm0
	mulss	.LCPI0_0(%rip), %xmm0
	cvtss2sd	%xmm0, %xmm0
	movl	$.L.str.18, %edi
	movb	$1, %al
	callq	printf
	movl	628(%rsp), %esi
	movl	$.L.str.19, %edi
	xorl	%eax, %eax
	callq	printf
	movl	616(%rsp), %esi
	movl	$.L.str.20, %edi
	xorl	%eax, %eax
	callq	printf
	cmpl	$0, 592(%rsp)
	movl	$.L.str.22, %esi
	cmoveq	%r14, %rsi
	movl	$.L.str.21, %edi
	xorl	%eax, %eax
	callq	printf
	incl	%ebp
	cmpl	12(%rsp), %ebp
	jl	.LBB0_4
.LBB0_13:                               # %._crit_edge
	movl	$.Lstr.1, %edi
	callq	puts@PLT
	xorl	%eax, %eax
	addq	$1488, %rsp                     # imm = 0x5D0
	.cfi_def_cfa_offset 32
	popq	%rbx
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	retq
.Lfunc_end0:
	.size	main, .Lfunc_end0-main
	.cfi_endproc
                                        # -- End function
	.type	.L.str.3,@object                # @.str.3
	.section	.rodata.str1.1,"aMS",@progbits,1
.L.str.3:
	.asciz	"There are %d devices supporting CUDA\n"
	.size	.L.str.3, 38

	.type	.L.str.4,@object                # @.str.4
.L.str.4:
	.asciz	"\nDevice %d: \"%s\"\n"
	.size	.L.str.4, 18

	.type	.L.str.5,@object                # @.str.5
.L.str.5:
	.asciz	"  Major revision number:                         %d\n"
	.size	.L.str.5, 53

	.type	.L.str.6,@object                # @.str.6
.L.str.6:
	.asciz	"  Minor revision number:                         %d\n"
	.size	.L.str.6, 53

	.type	.L.str.7,@object                # @.str.7
.L.str.7:
	.asciz	"  Total amount of global memory:                 %zd bytes\n"
	.size	.L.str.7, 60

	.type	.L.str.8,@object                # @.str.8
.L.str.8:
	.asciz	"  Total amount of constant memory:               %zd bytes\n"
	.size	.L.str.8, 60

	.type	.L.str.9,@object                # @.str.9
.L.str.9:
	.asciz	"  Total amount of shared memory per block:       %zd bytes\n"
	.size	.L.str.9, 60

	.type	.L.str.10,@object               # @.str.10
.L.str.10:
	.asciz	"  Total number of registers available per block: %d\n"
	.size	.L.str.10, 53

	.type	.L.str.11,@object               # @.str.11
.L.str.11:
	.asciz	"  Warp size:                                     %d\n"
	.size	.L.str.11, 53

	.type	.L.str.12,@object               # @.str.12
.L.str.12:
	.asciz	"  Maximum number of threads per block:           %d\n"
	.size	.L.str.12, 53

	.type	.L.str.13,@object               # @.str.13
.L.str.13:
	.asciz	"  Maximum sizes of each dimension of a block:    %d x %d x %d\n"
	.size	.L.str.13, 63

	.type	.L.str.14,@object               # @.str.14
.L.str.14:
	.asciz	"  Maximum sizes of each dimension of a grid:     %d x %d x %d\n"
	.size	.L.str.14, 63

	.type	.L.str.15,@object               # @.str.15
.L.str.15:
	.asciz	"  Maximum memory pitch:                          %zd bytes\n"
	.size	.L.str.15, 60

	.type	.L.str.16,@object               # @.str.16
.L.str.16:
	.asciz	"  Texture alignment:                             %zd bytes\n"
	.size	.L.str.16, 60

	.type	.L.str.17,@object               # @.str.17
.L.str.17:
	.asciz	"  Clock rate:                                    %.2f GHz\n"
	.size	.L.str.17, 59

	.type	.L.str.18,@object               # @.str.18
.L.str.18:
	.asciz	"  Memory Clock rate:                             %.2f GHz\n"
	.size	.L.str.18, 59

	.type	.L.str.19,@object               # @.str.19
.L.str.19:
	.asciz	"  Memory Bus Width:                              %d bits\n"
	.size	.L.str.19, 58

	.type	.L.str.20,@object               # @.str.20
.L.str.20:
	.asciz	"  Number of asynchronous engines:                %d\n"
	.size	.L.str.20, 53

	.type	.L.str.21,@object               # @.str.21
.L.str.21:
	.asciz	"  It can execute multiple kernels concurrently:  %s\n"
	.size	.L.str.21, 53

	.type	.L.str.22,@object               # @.str.22
.L.str.22:
	.asciz	"Yes"
	.size	.L.str.22, 4

	.type	.L.str.23,@object               # @.str.23
.L.str.23:
	.asciz	"No"
	.size	.L.str.23, 3

	.type	__hip_cuid_,@object             # @__hip_cuid_
	.bss
	.globl	__hip_cuid_
__hip_cuid_:
	.byte	0                               # 0x0
	.size	__hip_cuid_, 1

	.type	.Lstr,@object                   # @str
	.section	.rodata.str1.1,"aMS",@progbits,1
.Lstr:
	.asciz	"There is no device supporting CUDA"
	.size	.Lstr, 35

	.type	.Lstr.1,@object                 # @str.1
.Lstr.1:
	.asciz	"\nTEST PASSED"
	.size	.Lstr.1, 13

	.type	.Lstr.2,@object                 # @str.2
.Lstr.2:
	.asciz	"There is 1 device supporting CUDA"
	.size	.Lstr.2, 34

	.type	.Lstr.3,@object                 # @str.3
.Lstr.3:
	.asciz	"There is no device supporting CUDA."
	.size	.Lstr.3, 36

	.ident	"AMD clang version 18.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-6.3.2 25012 e5bf7e55c91490b07c49d8960fa7983d864936c4)"
	.section	".note.GNU-stack","",@progbits
	.addrsig
	.addrsig_sym __hip_cuid_

	.text
	.p2alignl 7, 3214868480
	.fill 96, 4, 3214868480
	.type	__hip_cuid_,@object             ; @__hip_cuid_
	.section	.bss,"aw",@nobits
	.globl	__hip_cuid_
__hip_cuid_:
	.byte	0                               ; 0x0
	.size	__hip_cuid_, 1

	.ident	"AMD clang version 18.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-6.3.2 25012 e5bf7e55c91490b07c49d8960fa7983d864936c4)"
	.section	".note.GNU-stack","",@progbits
	.addrsig
	.addrsig_sym __hip_cuid_
	.amdgcn_target "amdgcn-amd-amdhsa--gfx1100"
	.amdgpu_metadata
---
amdhsa.kernels:  []
amdhsa.target:   amdgcn-amd-amdhsa--gfx1100
amdhsa.version:
  - 1
  - 2
...

	.end_amdgpu_metadata
