Merge 'develop' into 'amd-staging'
Change-Id: I037144dd2fbf4e26f88525f2a820997fc3a23546
[ROCm/hip-tests commit: 4295c33aa2]
Этот коммит содержится в:
@@ -2160,7 +2160,8 @@ PREDEFINED = TEMPLATE_TEST_CASE(x)=x() \
|
||||
__linux__ \
|
||||
HT_AMD \
|
||||
HT_NVIDIA \
|
||||
__HIP_PLATFORM_NVCC__
|
||||
__HIP_PLATFORM_NVCC__ \
|
||||
__GNUC__
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||
# tag can be used to specify a list of macro names that should be expanded. The
|
||||
|
||||
@@ -5,21 +5,18 @@
|
||||
"Unit_hipMallocManaged_OverSubscription",
|
||||
"Unit_hipDeviceGetPCIBusId_Negative_PartialFill",
|
||||
"Unit_hipInit_Negative",
|
||||
"Unit_BuiltinAtomicsRTC_fmaxCoherentGlobalMem",
|
||||
"Unit_BuiltinAtomicsRTC__fminCoherentGlobalMem",
|
||||
"Unit_BuiltInAtomicAdd_CoherentGlobalMemWithRtc",
|
||||
"Unit_hipMemGetAddressRange_Negative",
|
||||
"Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Positive_Read_Write",
|
||||
"Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Negative_Parameters",
|
||||
"Unit_hipImportExternalMemory_Vulkan_Negative_Parameters",
|
||||
"Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Binary_Semaphore",
|
||||
"Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Multiple_Semaphores",
|
||||
"Unit_hipWaitExternalSemaphoresAsync_Vulkan_Negative_Parameters",
|
||||
"Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Binary_Semaphore",
|
||||
"Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Multiple_Semaphores",
|
||||
"Unit_hipSignalExternalSemaphoresAsync_Vulkan_Negative_Parameters",
|
||||
"Unit_hipImportExternalSemaphore_Vulkan_Negative_Parameters",
|
||||
"Unit_hipDestroyExternalSemaphore_Vulkan_Negative_Parameters"
|
||||
"Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Positive_Read_Write",
|
||||
"Unit_hipExternalMemoryGetMappedBuffer_Vulkan_Negative_Parameters",
|
||||
"Unit_hipImportExternalMemory_Vulkan_Negative_Parameters",
|
||||
"Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Binary_Semaphore",
|
||||
"Unit_hipWaitExternalSemaphoresAsync_Vulkan_Positive_Multiple_Semaphores",
|
||||
"Unit_hipWaitExternalSemaphoresAsync_Vulkan_Negative_Parameters",
|
||||
"Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Binary_Semaphore",
|
||||
"Unit_hipSignalExternalSemaphoresAsync_Vulkan_Positive_Multiple_Semaphores",
|
||||
"Unit_hipSignalExternalSemaphoresAsync_Vulkan_Negative_Parameters",
|
||||
"Unit_hipImportExternalSemaphore_Vulkan_Negative_Parameters",
|
||||
"Unit_hipDestroyExternalSemaphore_Vulkan_Negative_Parameters"
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,19 @@
|
||||
"Unit_hipInit_Negative",
|
||||
"Unit_hipDeviceReset_Positive_Basic",
|
||||
"Unit_hipDeviceReset_Positive_Threaded",
|
||||
"Unit_hipFuncSetCacheConfig_Positive_Basic",
|
||||
"Unit_hipFuncSetCacheConfig_Negative_Parameters",
|
||||
"Unit_hipFuncSetSharedMemConfig_Positive_Basic",
|
||||
"Unit_hipFuncSetSharedMemConfig_Negative_Parameters",
|
||||
"Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize",
|
||||
"Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout",
|
||||
"Unit_hipFuncSetAttribute_Positive_Parameters",
|
||||
"Unit_hipFuncSetAttribute_Negative_Parameters",
|
||||
"NOTE: The following 4 tests are disabled due to defect - EXSWHTEC-240",
|
||||
"Unit_hipFuncSetCacheConfig_Negative_Not_Supported",
|
||||
"Unit_hipFuncSetSharedMemConfig_Negative_Not_Supported",
|
||||
"Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize_Not_Supported",
|
||||
"Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout_Not_Supported",
|
||||
"Unit_hipOccupancyMaxActiveBlocksPerMultiprocessor_Negative_Parameters",
|
||||
"Unit_hipGraphMemcpyNodeSetParamsToSymbol_Positive_Basic",
|
||||
"Unit_hipGraphExecMemcpyNodeSetParamsToSymbol_Positive_Basic",
|
||||
@@ -26,7 +39,6 @@
|
||||
"Unit_hipDrvMemcpy3DAsync_Positive_Array",
|
||||
"Unit_hipMemRangeGetAttribute_Positive_AccessedBy_Basic",
|
||||
"Unit_hipMemRangeGetAttribute_Positive_AccessedBy_Partial_Range",
|
||||
"Unit_hipMemRangeGetAttributes_Negative_Parameters",
|
||||
"Unit_hipStreamAttachMemAsync_Positive_Basic",
|
||||
"Unit_hipStreamAttachMemAsync_Positive_AttachGlobal",
|
||||
"Unit_hipStreamAttachMemAsync_Negative_Parameters",
|
||||
@@ -34,6 +46,7 @@
|
||||
"Unit_hipGraphAddMemcpyNode1D_Negative_Basic",
|
||||
"intermittent issue: corrupted double-linked list",
|
||||
"Unit_hipGraphRetainUserObject_Functional_2",
|
||||
"Unit_ChannelDescriptor_Positive_16BitFloatingPoint",
|
||||
"intermittent issue: failure expected but sucess returned",
|
||||
"Unit_hipMemAdvise_NegtveTsts",
|
||||
"Note: Following four tests disabled due to defect - EXSWHTEC-203",
|
||||
@@ -44,7 +57,6 @@
|
||||
"Unit_hipIpcGetMemHandle_Positive_Unique_Handles_Separate_Allocations",
|
||||
"Unit_hipStreamCreateWithFlags_DefaultStreamInteraction",
|
||||
"Unit_hipStreamWaitEvent_UninitializedStream_Negative",
|
||||
"Unit_hipDeviceSetSharedMemConfig_Negative_Parameters",
|
||||
"Unit_hipMemset3DSync",
|
||||
"Unit_hipStreamAddCallback_StrmSyncTiming",
|
||||
"Disabling test tracked SWDEV-394199",
|
||||
@@ -85,6 +97,28 @@
|
||||
"=== Below tests fail in stress test on 30/06/23 ===",
|
||||
"Unit_hipStreamValue_Wait32_Blocking_NoMask_Nor",
|
||||
"Unit_hipStreamValue_Write - TestParams<uint32_t, PtrType::HostPtr>",
|
||||
"Unit_hipMemcpyParam2DAsync_multiDevice-StreamOnDiffDevice"
|
||||
"Unit_hipMemcpyParam2DAsync_multiDevice-StreamOnDiffDevice",
|
||||
"=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/96 ===",
|
||||
"Unit_hipHostGetDevicePointer_Negative",
|
||||
"=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/215 ===",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - long",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - unsigned long",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - ulong1",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - signed long",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - long1",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_2D - ulong2",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_2D - long2",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_4D - ulong4",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_4D - long4",
|
||||
"Unit_hipExtModuleLaunchKernel_NonUniformWorkGroup",
|
||||
"=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/18 ===",
|
||||
"Unit_hipMemcpyAsync_Negative_Parameters",
|
||||
"Unit_hipMemcpyDtoHAsync_Negative_Parameters",
|
||||
"Unit_hipMemcpyHtoDAsync_Negative_Parameters",
|
||||
"Unit_hipMemcpyDtoDAsync_Negative_Parameters",
|
||||
"=== Below tests fail in stress test on 13/07/23 ===",
|
||||
"Unit_deviceAllocation_Malloc_ComplexDataType",
|
||||
"Unit_deviceAllocation_New_ComplexDataType",
|
||||
"Unit_hipStreamValue_Wait32_Blocking_Mask_Eq_1"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -95,6 +95,19 @@
|
||||
"Unit_hipStreamSynchronize_NullStreamAndStreamPerThread",
|
||||
"Note: intermittent Seg fault failure ",
|
||||
"Unit_hipGraphAddEventRecordNode_Functional_WithoutFlags",
|
||||
"Unit_hipFuncSetCacheConfig_Positive_Basic",
|
||||
"Unit_hipFuncSetCacheConfig_Negative_Parameters",
|
||||
"Unit_hipFuncSetSharedMemConfig_Positive_Basic",
|
||||
"Unit_hipFuncSetSharedMemConfig_Negative_Parameters",
|
||||
"Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize",
|
||||
"Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout",
|
||||
"Unit_hipFuncSetAttribute_Positive_Parameters",
|
||||
"Unit_hipFuncSetAttribute_Negative_Parameters",
|
||||
"NOTE: The following 4 tests are disabled due to defect - EXSWHTEC-240",
|
||||
"Unit_hipFuncSetCacheConfig_Negative_Not_Supported",
|
||||
"Unit_hipFuncSetSharedMemConfig_Negative_Not_Supported",
|
||||
"Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize_Not_Supported",
|
||||
"Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout_Not_Supported",
|
||||
"Unit_hipOccupancyMaxActiveBlocksPerMultiprocessor_Negative_Parameters",
|
||||
"Unit_hipGraphMemcpyNodeSetParamsToSymbol_Positive_Basic",
|
||||
"Unit_hipGraphExecMemcpyNodeSetParamsToSymbol_Positive_Basic",
|
||||
@@ -137,6 +150,7 @@
|
||||
"Unit_hipStreamQuery_WithFinishedWork",
|
||||
"Unit_hipLaunchHostFunc_Graph",
|
||||
"Unit_hipLaunchHostFunc_KernelHost",
|
||||
"Unit_ChannelDescriptor_Positive_16BitFloatingPoint",
|
||||
"Unit_hipStreamSetCaptureDependencies_Positive_Functional",
|
||||
"Note: Following four tests disabled due to defect - EXSWHTEC-203",
|
||||
"Unit_hipGraphAddMemsetNode_Positive_Basic - uint16_t",
|
||||
@@ -150,7 +164,6 @@
|
||||
"Unit_hipGraphExecMemsetNodeSetParams_Positive_Basic - uint32_t",
|
||||
"Unit_hipGraphMemsetNodeSetParams_Positive_Basic - uint8_t",
|
||||
"Unit_hipStreamWaitEvent_UninitializedStream_Negative",
|
||||
"Unit_hipDeviceSetSharedMemConfig_Negative_Parameters",
|
||||
"Unit_hipDeviceGetUuid_Positive",
|
||||
"Disabling test tracked SWDEV-394199",
|
||||
"Unit_hipStreamCreateWithPriority_MulthreadNonblockingflag",
|
||||
@@ -172,6 +185,26 @@
|
||||
"SWDEV-398981 fails in stress test",
|
||||
"Unit_hipStreamCreateWithPriority_MulthreadDefaultflag",
|
||||
"Note: UUID returned empty on some windows nodes",
|
||||
"Unit_hipDeviceGetUuid_Positive"
|
||||
"Unit_hipDeviceGetUuid_Positive",
|
||||
"=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/96 ===",
|
||||
"Unit_hipHostGetDevicePointer_Negative",
|
||||
"=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/215 ===",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - long",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - unsigned long",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - ulong1",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - signed long",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - long1",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_2D - ulong2",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_2D - long2",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_3D - ulong3",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_3D - long3",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_4D - ulong4",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_4D - long4",
|
||||
"Unit_hipExtModuleLaunchKernel_NonUniformWorkGroup",
|
||||
"=== Below tests fail in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/18 ===",
|
||||
"Unit_hipMemcpyAsync_Negative_Parameters",
|
||||
"Unit_hipMemcpyDtoHAsync_Negative_Parameters",
|
||||
"Unit_hipMemcpyHtoDAsync_Negative_Parameters",
|
||||
"Unit_hipMemcpyDtoDAsync_Negative_Parameters"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"DisabledTests":
|
||||
[
|
||||
"Unit_hipFuncSetCacheConfig_Negative_Not_Supported",
|
||||
"Unit_hipFuncSetSharedMemConfig_Negative_Not_Supported",
|
||||
"Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize_Not_Supported",
|
||||
"Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout_Not_Supported",
|
||||
"=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/85 ===",
|
||||
"Unit_hipFuncSetAttribute_Negative_Parameters",
|
||||
"=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/215 ===",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - long",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - unsigned long",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - ulong1",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - signed long",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - long1",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_2D - ulong2",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_2D - long2",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_3D - ulong3",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_3D - long3",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_4D - ulong4",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_4D - long4",
|
||||
"=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/38 ===",
|
||||
"Unit_hipFreeAsync_negative"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"DisabledTests":
|
||||
[
|
||||
"Unit_hipFuncSetCacheConfig_Negative_Not_Supported",
|
||||
"Unit_hipFuncSetSharedMemConfig_Negative_Not_Supported",
|
||||
"Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize_Not_Supported",
|
||||
"Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout_Not_Supported",
|
||||
"=== Below test fails in external CI for PR https://github.com/ROCm-Developer-Tools/hip-tests/pull/215 ===",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - long",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - unsigned long",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - ulong1",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - signed long",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_1D - long1",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_2D - ulong2",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_2D - long2",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_3D - ulong3",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_3D - long3",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_4D - ulong4",
|
||||
"Unit_ChannelDescriptor_Positive_Basic_4D - long4"
|
||||
]
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2021 - 2022 Advanced Micro Devices, Inc. All rights reserved.
|
||||
Copyright (c) 2021 - 2023 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
|
||||
@@ -72,6 +72,20 @@ THE SOFTWARE.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup DeviceLanguageTest Device Language
|
||||
* @{
|
||||
* This section describes tests for the Device Language API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ExecutionTest Execution Control
|
||||
* @{
|
||||
* This section describes tests for the execution control functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ShflTest warp shuffle function Management
|
||||
* @{
|
||||
@@ -93,3 +107,24 @@ THE SOFTWARE.
|
||||
* This section describes the stream management types & functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup DynamicLoadingTest Kernel Loading Management
|
||||
* @{
|
||||
* This section describes the different kernel launch approaches.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup MemoryTest memory Management APIs
|
||||
* @{
|
||||
* This section describes the memory management types & functions of HIP runtime API.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup KernelTest Kernel Functions Management
|
||||
* @{
|
||||
* This section describes the various kernel functions invocation.
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -81,13 +81,16 @@ static void TstCoherency(int *Ptr, bool HmmMem) {
|
||||
|
||||
// Getting gpu frequency
|
||||
if (IsGfx11()) {
|
||||
HIPCHECK(hipDeviceGetAttribute(&peak_clk, hipDeviceAttributeWallClockRate, 0));
|
||||
HIPCHECK(hipDeviceGetAttribute(&peak_clk,
|
||||
hipDeviceAttributeWallClockRate, 0));
|
||||
} else {
|
||||
HIPCHECK(hipDeviceGetAttribute(&peak_clk, hipDeviceAttributeClockRate, 0));
|
||||
HIPCHECK(hipDeviceGetAttribute(&peak_clk,
|
||||
hipDeviceAttributeClockRate, 0));
|
||||
}
|
||||
|
||||
if (!HmmMem) {
|
||||
HIP_CHECK(hipHostGetDevicePointer(reinterpret_cast<void **>(&Dptr), Ptr, 0));
|
||||
HIP_CHECK(hipHostGetDevicePointer(reinterpret_cast<void **>(&Dptr),
|
||||
Ptr, 0));
|
||||
if (IsGfx11()) {
|
||||
CoherentTst_gfx11<<<1, 1, 0, strm>>>(Dptr, peak_clk);
|
||||
} else {
|
||||
@@ -122,58 +125,13 @@ static void TstCoherency(int *Ptr, bool HmmMem) {
|
||||
// The following test is failing on Nvidia platform hence disabled it for now
|
||||
#if HT_AMD
|
||||
TEST_CASE("Unit_malloc_CoherentTst") {
|
||||
if ((setenv("HSA_XNACK", "1", 1)) != 0) {
|
||||
WARN("Unable to turn on HSA_XNACK, hence terminating the Test case!");
|
||||
REQUIRE(false);
|
||||
}
|
||||
// The following code block is used to check for gfx906/8 so as to skip if
|
||||
// any of the gpus available
|
||||
int fd1[2]; // Used to store two ends of first pipe
|
||||
pid_t p;
|
||||
if (pipe(fd1) == -1) {
|
||||
fprintf(stderr, "Pipe Failed");
|
||||
REQUIRE(false);
|
||||
}
|
||||
|
||||
/* GpuId[0] for gfx90a exists--> 1 for yes and 0 for no*/
|
||||
int GpuId[1] = {0};
|
||||
p = fork();
|
||||
|
||||
if (p < 0) {
|
||||
fprintf(stderr, "fork Failed");
|
||||
REQUIRE(false);
|
||||
} else if (p > 0) { // parent process
|
||||
close(fd1[1]); // Close writing end of first pipe
|
||||
// Wait for child to send a string
|
||||
wait(NULL);
|
||||
// Read string from child and close reading end.
|
||||
read(fd1[0], GpuId, 2 * sizeof(int));
|
||||
close(fd1[0]);
|
||||
if (GpuId[0] == 0) {
|
||||
WARN("This test is applicable for MI200."
|
||||
"Skipping the test!!");
|
||||
exit(0);
|
||||
}
|
||||
} else { // child process
|
||||
close(fd1[0]); // Close read end of first pipe
|
||||
hipDeviceProp_t prop;
|
||||
HIPCHECK(hipGetDeviceProperties(&prop, 0));
|
||||
char *p = NULL;
|
||||
|
||||
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_FINEGRAIN_HWSUPPORT, prop.gcnArchName)) {
|
||||
WARN("gfx90a gpu found on this system!!");
|
||||
GpuId[0] = 1;
|
||||
}
|
||||
|
||||
// Write concatenated string and close writing end
|
||||
write(fd1[1], GpuId, 2 * sizeof(int));
|
||||
close(fd1[1]);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// Test Case execution begins from here
|
||||
int stat = 0;
|
||||
if (fork() == 0) {
|
||||
hipDeviceProp_t prop;
|
||||
HIPCHECK(hipGetDeviceProperties(&prop, 0));
|
||||
char *p = NULL;
|
||||
p = strstr(prop.gcnArchName, "xnack+");
|
||||
if (p) {
|
||||
// Test Case execution begins from here
|
||||
int stat = 0;
|
||||
int managed = 0;
|
||||
HIPCHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory,
|
||||
0));
|
||||
@@ -185,23 +143,10 @@ TEST_CASE("Unit_malloc_CoherentTst") {
|
||||
Ptr = reinterpret_cast<int*>(malloc(SIZE));
|
||||
TstCoherency(Ptr, HmmMem);
|
||||
free(Ptr);
|
||||
if (YES_COHERENT) {
|
||||
// exit() with code 10 which indicates pass
|
||||
exit(10);
|
||||
} else {
|
||||
// exit() with code 9 which indicates fail
|
||||
exit(9);
|
||||
}
|
||||
} else {
|
||||
SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory "
|
||||
"attribute. Hence skipping the testing with Pass result.\n");
|
||||
}
|
||||
REQUIRE(YES_COHERENT);
|
||||
}
|
||||
} else {
|
||||
wait(&stat);
|
||||
int Result = WEXITSTATUS(stat);
|
||||
if (Result != 10) {
|
||||
REQUIRE(false);
|
||||
}
|
||||
HipTest::HIP_SKIP_TEST("GPU is not xnack enabled hence skipping the test...\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -212,55 +157,12 @@ TEST_CASE("Unit_malloc_CoherentTst") {
|
||||
// The following test is failing on Nvidia platform hence disabling it for now
|
||||
#if HT_AMD
|
||||
TEST_CASE("Unit_malloc_CoherentTstWthAdvise") {
|
||||
if ((setenv("HSA_XNACK", "1", 1)) != 0) {
|
||||
WARN("Unable to turn on HSA_XNACK, hence terminating the Test case!");
|
||||
REQUIRE(false);
|
||||
}
|
||||
// The following code block is used to check for gfx906/8 so as to skip if
|
||||
// any of the gpus available
|
||||
int fd1[2]; // Used to store two ends of first pipe
|
||||
pid_t p;
|
||||
if (pipe(fd1) == -1) {
|
||||
fprintf(stderr, "Pipe Failed");
|
||||
REQUIRE(false);
|
||||
}
|
||||
|
||||
/* GpuId[0] for gfx90a exists--> 1 for yes and 0 for no */
|
||||
int GpuId[1] = {0};
|
||||
p = fork();
|
||||
|
||||
if (p < 0) {
|
||||
fprintf(stderr, "fork Failed");
|
||||
REQUIRE(false);
|
||||
} else if (p > 0) { // parent process
|
||||
close(fd1[1]); // Close writing end of first pipe
|
||||
// Wait for child to send a string
|
||||
wait(NULL);
|
||||
// Read string from child and close reading end.
|
||||
read(fd1[0], GpuId, 2 * sizeof(int));
|
||||
close(fd1[0]);
|
||||
if (GpuId[0] == 0) {
|
||||
WARN("This test is applicable for MI200."
|
||||
"Skipping the test!!");
|
||||
exit(0);
|
||||
}
|
||||
} else { // child process
|
||||
close(fd1[0]); // Close read end of first pipe
|
||||
hipDeviceProp_t prop;
|
||||
HIPCHECK(hipGetDeviceProperties(&prop, 0));
|
||||
char *p = NULL;
|
||||
p = strstr(prop.gcnArchName, "gfx90a");
|
||||
if (p) {
|
||||
WARN("gfx90a gpu found on this system!!");
|
||||
GpuId[0] = 1;
|
||||
}
|
||||
// Write concatenated string and close writing end
|
||||
write(fd1[1], GpuId, 2 * sizeof(int));
|
||||
close(fd1[1]);
|
||||
exit(0);
|
||||
}
|
||||
int stat = 0;
|
||||
if (fork() == 0) {
|
||||
hipDeviceProp_t prop;
|
||||
HIPCHECK(hipGetDeviceProperties(&prop, 0));
|
||||
char *p = NULL;
|
||||
p = strstr(prop.gcnArchName, "xnack+");
|
||||
if (p) {
|
||||
int stat = 0;
|
||||
int managed = 0;
|
||||
HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory,
|
||||
0));
|
||||
@@ -275,25 +177,10 @@ TEST_CASE("Unit_malloc_CoherentTstWthAdvise") {
|
||||
SquareKrnl<<<1, 1, 0, strm>>>(Ptr);
|
||||
HIP_CHECK(hipStreamSynchronize(strm));
|
||||
HIP_CHECK(hipStreamDestroy(strm));
|
||||
if (*Ptr == 16) {
|
||||
// exit() with code 10 which indicates pass
|
||||
free(Ptr);
|
||||
exit(10);
|
||||
} else {
|
||||
// exit() with code 9 which indicates fail
|
||||
free(Ptr);
|
||||
exit(9);
|
||||
}
|
||||
} else {
|
||||
SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory "
|
||||
"attribute. Hence skipping the testing with Pass result.\n");
|
||||
REQUIRE (*Ptr == 16);
|
||||
}
|
||||
} else {
|
||||
wait(&stat);
|
||||
int Result = WEXITSTATUS(stat);
|
||||
if (Result != 10) {
|
||||
REQUIRE(false);
|
||||
}
|
||||
HipTest::HIP_SKIP_TEST("GPU is not xnack enabled hence skipping the test...\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -303,55 +190,12 @@ TEST_CASE("Unit_malloc_CoherentTstWthAdvise") {
|
||||
// The following test is failing on Nvidia platform hence disabling it for now
|
||||
#if HT_AMD
|
||||
TEST_CASE("Unit_mmap_CoherentTst") {
|
||||
if ((setenv("HSA_XNACK", "1", 1)) != 0) {
|
||||
WARN("Unable to turn on HSA_XNACK, hence terminating the Test case!");
|
||||
REQUIRE(false);
|
||||
}
|
||||
// The following code block is used to check for gfx906/8 so as to skip if
|
||||
// any of the gpus available
|
||||
int fd1[2]; // Used to store two ends of first pipe
|
||||
pid_t p;
|
||||
if (pipe(fd1) == -1) {
|
||||
fprintf(stderr, "Pipe Failed");
|
||||
REQUIRE(false);
|
||||
}
|
||||
|
||||
/* GpuId[0] for gfx90a exists--> 1 for yes and 0 for no */
|
||||
int GpuId[1] = {0};
|
||||
p = fork();
|
||||
|
||||
if (p < 0) {
|
||||
fprintf(stderr, "fork Failed");
|
||||
REQUIRE(false);
|
||||
} else if (p > 0) { // parent process
|
||||
close(fd1[1]); // Close writing end of first pipe
|
||||
// Wait for child to send a string
|
||||
wait(NULL);
|
||||
// Read string from child and close reading end.
|
||||
read(fd1[0], GpuId, 2 * sizeof(int));
|
||||
close(fd1[0]);
|
||||
if (GpuId[0] == 0) {
|
||||
WARN("This test is not applicable for MI200."
|
||||
"Skipping the test!!");
|
||||
exit(0);
|
||||
}
|
||||
} else { // child process
|
||||
close(fd1[0]); // Close read end of first pipe
|
||||
hipDeviceProp_t prop;
|
||||
HIPCHECK(hipGetDeviceProperties(&prop, 0));
|
||||
char *p = NULL;
|
||||
p = strstr(prop.gcnArchName, "gfx90a");
|
||||
if (p) {
|
||||
WARN("gfx90a gpu found on this system!!");
|
||||
GpuId[0] = 1;
|
||||
}
|
||||
// Write concatenated string and close writing end
|
||||
write(fd1[1], GpuId, 2 * sizeof(int));
|
||||
close(fd1[1]);
|
||||
exit(0);
|
||||
}
|
||||
int stat = 0;
|
||||
if (fork() == 0) {
|
||||
hipDeviceProp_t prop;
|
||||
HIPCHECK(hipGetDeviceProperties(&prop, 0));
|
||||
char *p = NULL;
|
||||
p = strstr(prop.gcnArchName, "xnack+");
|
||||
if (p) {
|
||||
int stat = 0;
|
||||
int managed = 0;
|
||||
HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory,
|
||||
0));
|
||||
@@ -371,21 +215,10 @@ TEST_CASE("Unit_mmap_CoherentTst") {
|
||||
if (err != 0) {
|
||||
WARN("munmap failed\n");
|
||||
}
|
||||
if (YES_COHERENT) {
|
||||
exit(10);
|
||||
} else {
|
||||
exit(9);
|
||||
}
|
||||
} else {
|
||||
SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory "
|
||||
"attribute. Hence skipping the testing with Pass result.\n");
|
||||
}
|
||||
REQUIRE(YES_COHERENT);
|
||||
}
|
||||
} else {
|
||||
wait(&stat);
|
||||
int Result = WEXITSTATUS(stat);
|
||||
if (Result != 10) {
|
||||
REQUIRE(false);
|
||||
}
|
||||
HipTest::HIP_SKIP_TEST("GPU is not xnack enabled hence skipping the test...\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -395,55 +228,12 @@ TEST_CASE("Unit_mmap_CoherentTst") {
|
||||
// The following test is failing on Nvidia platform hence disabling it for now
|
||||
#if HT_AMD
|
||||
TEST_CASE("Unit_mmap_CoherentTstWthAdvise") {
|
||||
if ((setenv("HSA_XNACK", "1", 1)) != 0) {
|
||||
WARN("Unable to turn on HSA_XNACK, hence terminating the Test case!");
|
||||
REQUIRE(false);
|
||||
}
|
||||
// The following code block is used to check for gfx906/8 so as to skip if
|
||||
// any of the gpus available
|
||||
int fd1[2]; // Used to store two ends of first pipe
|
||||
pid_t p;
|
||||
if (pipe(fd1) == -1) {
|
||||
fprintf(stderr, "Pipe Failed");
|
||||
REQUIRE(false);
|
||||
}
|
||||
|
||||
/* GpuId[0] for gfx90a exists--> 1 for yes and 0 for no */
|
||||
int GpuId[1] = {0};
|
||||
p = fork();
|
||||
|
||||
if (p < 0) {
|
||||
fprintf(stderr, "fork Failed");
|
||||
REQUIRE(false);
|
||||
} else if (p > 0) { // parent process
|
||||
close(fd1[1]); // Close writing end of first pipe
|
||||
// Wait for child to send a string
|
||||
wait(NULL);
|
||||
// Read string from child and close reading end.
|
||||
read(fd1[0], GpuId, 2 * sizeof(int));
|
||||
close(fd1[0]);
|
||||
if (GpuId[0] == 0) {
|
||||
WARN("This test is applicable for MI200."
|
||||
"Skipping the test!!");
|
||||
exit(0);
|
||||
}
|
||||
} else { // child process
|
||||
close(fd1[0]); // Close read end of first pipe
|
||||
hipDeviceProp_t prop;
|
||||
HIPCHECK(hipGetDeviceProperties(&prop, 0));
|
||||
char *p = NULL;
|
||||
p = strstr(prop.gcnArchName, "gfx90a");
|
||||
if (p) {
|
||||
WARN("gfx90a gpu found on this system!!");
|
||||
GpuId[0] = 1;
|
||||
}
|
||||
// Write concatenated string and close writing end
|
||||
write(fd1[1], GpuId, 2 * sizeof(int));
|
||||
close(fd1[1]);
|
||||
exit(0);
|
||||
}
|
||||
int stat = 0;
|
||||
if (fork() == 0) {
|
||||
hipDeviceProp_t prop;
|
||||
HIPCHECK(hipGetDeviceProperties(&prop, 0));
|
||||
char *p = NULL;
|
||||
p = strstr(prop.gcnArchName, "xnack+");
|
||||
if (p) {
|
||||
int stat = 0;
|
||||
int managed = 0;
|
||||
HIP_CHECK(hipDeviceGetAttribute(&managed, hipDeviceAttributeManagedMemory,
|
||||
0));
|
||||
@@ -466,26 +256,15 @@ TEST_CASE("Unit_mmap_CoherentTstWthAdvise") {
|
||||
bool IfTstPassed = false;
|
||||
if (*Ptr == 81) {
|
||||
IfTstPassed = true;
|
||||
}
|
||||
}
|
||||
int err = munmap(Ptr, SIZE);
|
||||
if (err != 0) {
|
||||
WARN("munmap failed\n");
|
||||
}
|
||||
if (IfTstPassed) {
|
||||
exit(10);
|
||||
} else {
|
||||
exit(9);
|
||||
}
|
||||
} else {
|
||||
SUCCEED("GPU 0 doesn't support hipDeviceAttributeManagedMemory "
|
||||
"attribute. Hence skipping the testing with Pass result.\n");
|
||||
}
|
||||
REQUIRE(IfTstPassed);
|
||||
}
|
||||
} else {
|
||||
wait(&stat);
|
||||
int Result = WEXITSTATUS(stat);
|
||||
if (Result != 10) {
|
||||
REQUIRE(false);
|
||||
}
|
||||
HipTest::HIP_SKIP_TEST("GPU is not xnack enabled hence skipping the test...\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2023 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
# Copyright (c) 2021-2023 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
|
||||
@@ -36,6 +36,12 @@ add_subdirectory(compiler)
|
||||
add_subdirectory(errorHandling)
|
||||
add_subdirectory(cooperativeGrps)
|
||||
add_subdirectory(context)
|
||||
add_subdirectory(dynamicLoading)
|
||||
add_subdirectory(g++)
|
||||
add_subdirectory(module)
|
||||
add_subdirectory(channelDescriptor)
|
||||
add_subdirectory(executionControl)
|
||||
|
||||
if(HIP_PLATFORM STREQUAL "amd")
|
||||
add_subdirectory(callback)
|
||||
#add_subdirectory(clock)
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# Copyright (c) 2022 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.
|
||||
|
||||
set(TEST_SRC
|
||||
channel_descriptor.cc
|
||||
)
|
||||
|
||||
hip_add_exe_to_target(NAME ChannelDescriptorTest
|
||||
TEST_SRC ${TEST_SRC}
|
||||
TEST_TARGET_NAME build_tests)
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 "channel_descriptor_common.hh"
|
||||
|
||||
/**
|
||||
* @addtogroup hipCreateChannelDesc hipCreateChannelDesc
|
||||
* @{
|
||||
* @ingroup DeviceLanguageTest
|
||||
* `hipCreateChannelDesc<T>()` -
|
||||
* Creates a dedicated channel descriptor based on passed built-in or vector type T.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Validates that 1D channel descriptor is created as expected.
|
||||
* - Compares channel descriptor with the manually created one.
|
||||
* - Takes into consideration following 1D built-in and vector types:
|
||||
* -# char (signed and unsigned)
|
||||
* -# short (signed and unsigned)
|
||||
* -# int (signed and unsigned)
|
||||
* -# float
|
||||
* -# long (signed and unsigned)
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/channelDescriptor/channel_descriptor.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEMPLATE_TEST_CASE("Unit_ChannelDescriptor_Positive_Basic_1D", "", char, unsigned char, uchar1,
|
||||
signed char, char1, unsigned short, ushort1, short, signed short, short1, int,
|
||||
unsigned int, uint1, signed int, int1, float, float1, long, unsigned long,
|
||||
ulong1, signed long, long1) {
|
||||
ChannelDescriptorTest1D<TestType> channel_desc_test;
|
||||
channel_desc_test.Run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Validates that 2D channel descriptor is created as expected.
|
||||
* - Compares channel descriptor with the manually created one.
|
||||
* - Takes into consideration following 2D built-in and vector types:
|
||||
* -# char (signed and unsigned)
|
||||
* -# short (signed and unsigned)
|
||||
* -# int (signed and unsigned)
|
||||
* -# float
|
||||
* -# long (signed and unsigned)
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/channelDescriptor/channel_descriptor.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEMPLATE_TEST_CASE("Unit_ChannelDescriptor_Positive_Basic_2D", "", uchar2, char2, ushort2, short2,
|
||||
uint2, int2, float2, ulong2, long2) {
|
||||
ChannelDescriptorTest2D<TestType> channel_desc_test;
|
||||
channel_desc_test.Run();
|
||||
}
|
||||
|
||||
#ifndef __GNUC__
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Validates that 3D channel descriptor is created as expected.
|
||||
* - Compares channel descriptor with the manually created one.
|
||||
* - Takes into consideration following 3D built-in and vector types:
|
||||
* -# char (signed and unsigned)
|
||||
* -# short (signed and unsigned)
|
||||
* -# int (signed and unsigned)
|
||||
* -# float
|
||||
* -# long (signed and unsigned)
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/channelDescriptor/channel_descriptor.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.2
|
||||
* - Available for non-GNUC compilers.
|
||||
*/
|
||||
TEMPLATE_TEST_CASE("Unit_ChannelDescriptor_Positive_Basic_3D", "", uchar3, char3, ushort3, short3,
|
||||
uint3, int3, float3, ulong3, long3) {
|
||||
ChannelDescriptorTest3D<TestType> channel_desc_test;
|
||||
channel_desc_test.Run();
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Validates that 4D channel descriptor is created as expected.
|
||||
* - Compares channel descriptor with the manually created one.
|
||||
* - Takes into consideration following 4D built-in and vector types:
|
||||
* -# char (signed and unsigned)
|
||||
* -# short (signed and unsigned)
|
||||
* -# int (signed and unsigned)
|
||||
* -# float
|
||||
* -# long (signed and unsigned)
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/channelDescriptor/channel_descriptor.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEMPLATE_TEST_CASE("Unit_ChannelDescriptor_Positive_Basic_4D", "", uchar4, char4, ushort4, short4,
|
||||
uint4, int4, float4, ulong4, long4) {
|
||||
ChannelDescriptorTest4D<TestType> channel_desc_test;
|
||||
channel_desc_test.Run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Validates that an empty channel descriptor is created as expected.
|
||||
* - Compares channel descriptor with the manually created one.
|
||||
* - Takes into consideration all dimensions of the following built-in and vector types:
|
||||
* -# long long (signed and unsigned)
|
||||
* -# double
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/channelDescriptor/channel_descriptor.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEMPLATE_TEST_CASE("Unit_ChannelDescriptor_Positive_FormatNone", "", long long, signed long long,
|
||||
unsigned long long, longlong1, longlong2, longlong3, longlong4, ulonglong1,
|
||||
ulonglong2, ulonglong3, ulonglong4, double1, double2, double3, double4) {
|
||||
ChannelDescriptorTestNone<TestType> channel_desc_test;
|
||||
channel_desc_test.Run();
|
||||
}
|
||||
|
||||
#if HT_AMD
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Validates that the channel descriptor is created as expected.
|
||||
* - Compares channel descriptor with the manually created one.
|
||||
* - Takes into consideration 16-bit floating-point type.
|
||||
* -# Creates 1D channel descriptor.
|
||||
* -# Creates 2D channel descriptor.
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/channelDescriptor/channel_descriptor.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEST_CASE("Unit_ChannelDescriptor_Positive_16BitFloatingPoint") {
|
||||
int size = static_cast<int>(sizeof(unsigned short) * 8);
|
||||
hipChannelFormatKind kind = hipChannelFormatKindFloat;
|
||||
hipChannelFormatDesc channel_desc{};
|
||||
hipChannelFormatDesc referent_channel_desc{};
|
||||
|
||||
SECTION("hipCreateChannelDescHalf") {
|
||||
referent_channel_desc = {size, 0, 0, 0, kind};
|
||||
channel_desc = hipCreateChannelDescHalf();
|
||||
}
|
||||
SECTION("hipCreateChannelDescHalf1") {
|
||||
referent_channel_desc = {size, 0, 0, 0, kind};
|
||||
channel_desc = hipCreateChannelDescHalf1();
|
||||
}
|
||||
SECTION("hipCreateChannelDescHalf2") {
|
||||
referent_channel_desc = {size, size, 0, 0, kind};
|
||||
channel_desc = hipCreateChannelDescHalf2();
|
||||
}
|
||||
|
||||
REQUIRE(channel_desc.x == referent_channel_desc.x);
|
||||
REQUIRE(channel_desc.y == referent_channel_desc.y);
|
||||
REQUIRE(channel_desc.z == referent_channel_desc.z);
|
||||
REQUIRE(channel_desc.w == referent_channel_desc.w);
|
||||
REQUIRE(channel_desc.f == referent_channel_desc.f);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 <hip_test_common.hh>
|
||||
|
||||
enum class ChannelDimension { OneDim, TwoDim, ThreeDim, FourDim };
|
||||
|
||||
template <typename T> class ChannelDescriptorTestShell {
|
||||
protected:
|
||||
int size;
|
||||
hipChannelFormatKind kind;
|
||||
ChannelDimension dimension;
|
||||
virtual void SetSizeAndKind() = 0;
|
||||
|
||||
public:
|
||||
void Run() {
|
||||
hipChannelFormatDesc channel_desc{};
|
||||
SetSizeAndKind();
|
||||
hipChannelFormatDesc referent_channel_desc{0, 0, 0, 0, kind};
|
||||
switch (dimension) {
|
||||
case ChannelDimension::FourDim:
|
||||
referent_channel_desc.w = size;
|
||||
case ChannelDimension::ThreeDim:
|
||||
referent_channel_desc.z = size;
|
||||
case ChannelDimension::TwoDim:
|
||||
referent_channel_desc.y = size;
|
||||
default:
|
||||
referent_channel_desc.x = size;
|
||||
}
|
||||
channel_desc = hipCreateChannelDesc<T>();
|
||||
REQUIRE(channel_desc.x == referent_channel_desc.x);
|
||||
REQUIRE(channel_desc.y == referent_channel_desc.y);
|
||||
REQUIRE(channel_desc.z == referent_channel_desc.z);
|
||||
REQUIRE(channel_desc.w == referent_channel_desc.w);
|
||||
REQUIRE(channel_desc.f == referent_channel_desc.f);
|
||||
}
|
||||
|
||||
ChannelDescriptorTestShell(const ChannelDimension dimension)
|
||||
: size(0), kind(hipChannelFormatKindNone), dimension(dimension) {}
|
||||
ChannelDescriptorTestShell(const ChannelDescriptorTestShell&) = delete;
|
||||
ChannelDescriptorTestShell(ChannelDescriptorTestShell&&) = delete;
|
||||
};
|
||||
|
||||
template <typename T> class ChannelDescriptorTest1D : public ChannelDescriptorTestShell<T> {
|
||||
public:
|
||||
ChannelDescriptorTest1D() : ChannelDescriptorTestShell<T>(ChannelDimension::OneDim) {}
|
||||
|
||||
protected:
|
||||
void SetSizeAndKind() {
|
||||
if (std::is_same_v<char, T>) {
|
||||
this->size = static_cast<int>(sizeof(char) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
} else if (std::is_same_v<unsigned char, T> || std::is_same_v<uchar1, T>) {
|
||||
this->size = static_cast<int>(sizeof(unsigned char) * 8);
|
||||
this->kind = hipChannelFormatKindUnsigned;
|
||||
} else if (std::is_same_v<signed char, T> || std::is_same_v<char1, T>) {
|
||||
this->size = static_cast<int>(sizeof(signed char) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
} else if (std::is_same_v<unsigned short, T> || std::is_same_v<ushort1, T>) {
|
||||
this->size = static_cast<int>(sizeof(unsigned short) * 8);
|
||||
this->kind = hipChannelFormatKindUnsigned;
|
||||
} else if (std::is_same_v<short, T> || std::is_same_v<signed short, T> ||
|
||||
std::is_same_v<short1, T>) {
|
||||
this->size = static_cast<int>(sizeof(signed short) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
} else if (std::is_same_v<unsigned int, T> || std::is_same_v<uint1, T>) {
|
||||
this->size = static_cast<int>(sizeof(unsigned int) * 8);
|
||||
this->kind = hipChannelFormatKindUnsigned;
|
||||
} else if (std::is_same_v<int, T> || std::is_same_v<signed int, T> || std::is_same_v<int1, T>) {
|
||||
this->size = static_cast<int>(sizeof(signed int) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
} else if (std::is_same_v<float, T> || std::is_same_v<float1, T>) {
|
||||
this->size = static_cast<int>(sizeof(float) * 8);
|
||||
this->kind = hipChannelFormatKindFloat;
|
||||
} else if (std::is_same_v<unsigned long, T> || std::is_same_v<ulong1, T>) {
|
||||
this->size = static_cast<int>(sizeof(unsigned long) * 8);
|
||||
this->kind = hipChannelFormatKindUnsigned;
|
||||
} else if (std::is_same_v<long, T> || std::is_same_v<signed long, T> ||
|
||||
std::is_same_v<long1, T>) {
|
||||
this->size = static_cast<int>(sizeof(signed long) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> class ChannelDescriptorTest2D : public ChannelDescriptorTestShell<T> {
|
||||
public:
|
||||
ChannelDescriptorTest2D() : ChannelDescriptorTestShell<T>(ChannelDimension::TwoDim) {}
|
||||
|
||||
protected:
|
||||
void SetSizeAndKind() {
|
||||
if (std::is_same_v<uchar2, T>) {
|
||||
this->size = static_cast<int>(sizeof(unsigned char) * 8);
|
||||
this->kind = hipChannelFormatKindUnsigned;
|
||||
} else if (std::is_same_v<char2, T>) {
|
||||
this->size = static_cast<int>(sizeof(signed char) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
} else if (std::is_same_v<ushort2, T>) {
|
||||
this->size = static_cast<int>(sizeof(unsigned short) * 8);
|
||||
this->kind = hipChannelFormatKindUnsigned;
|
||||
} else if (std::is_same_v<short2, T>) {
|
||||
this->size = static_cast<int>(sizeof(signed short) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
} else if (std::is_same_v<uint2, T>) {
|
||||
this->size = static_cast<int>(sizeof(unsigned int) * 8);
|
||||
this->kind = hipChannelFormatKindUnsigned;
|
||||
} else if (std::is_same_v<int2, T>) {
|
||||
this->size = static_cast<int>(sizeof(signed int) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
} else if (std::is_same_v<float2, T>) {
|
||||
this->size = static_cast<int>(sizeof(float) * 8);
|
||||
this->kind = hipChannelFormatKindFloat;
|
||||
} else if (std::is_same_v<ulong2, T>) {
|
||||
this->size = static_cast<int>(sizeof(unsigned long) * 8);
|
||||
this->kind = hipChannelFormatKindUnsigned;
|
||||
} else if (std::is_same_v<long2, T>) {
|
||||
this->size = static_cast<int>(sizeof(signed long) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef __GNUC__
|
||||
template <typename T> class ChannelDescriptorTest3D : public ChannelDescriptorTestShell<T> {
|
||||
public:
|
||||
ChannelDescriptorTest3D() : ChannelDescriptorTestShell<T>(ChannelDimension::ThreeDim) {}
|
||||
|
||||
protected:
|
||||
void SetSizeAndKind() {
|
||||
if (std::is_same_v<uchar3, T>) {
|
||||
this->size = static_cast<int>(sizeof(unsigned char) * 8);
|
||||
this->kind = hipChannelFormatKindUnsigned;
|
||||
} else if (std::is_same_v<char3, T>) {
|
||||
this->size = static_cast<int>(sizeof(signed char) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
} else if (std::is_same_v<ushort3, T>) {
|
||||
this->size = static_cast<int>(sizeof(unsigned short) * 8);
|
||||
this->kind = hipChannelFormatKindUnsigned;
|
||||
} else if (std::is_same_v<short3, T>) {
|
||||
this->size = static_cast<int>(sizeof(signed short) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
} else if (std::is_same_v<uint3, T>) {
|
||||
this->size = static_cast<int>(sizeof(unsigned int) * 8);
|
||||
this->kind = hipChannelFormatKindUnsigned;
|
||||
} else if (std::is_same_v<int3, T>) {
|
||||
this->size = static_cast<int>(sizeof(signed int) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
} else if (std::is_same_v<float3, T>) {
|
||||
this->size = static_cast<int>(sizeof(float) * 8);
|
||||
this->kind = hipChannelFormatKindFloat;
|
||||
} else if (std::is_same_v<ulong3, T>) {
|
||||
this->size = static_cast<int>(sizeof(unsigned long) * 8);
|
||||
this->kind = hipChannelFormatKindUnsigned;
|
||||
} else if (std::is_same_v<long3, T>) {
|
||||
this->size = static_cast<int>(sizeof(signed long) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename T> class ChannelDescriptorTest4D : public ChannelDescriptorTestShell<T> {
|
||||
public:
|
||||
ChannelDescriptorTest4D() : ChannelDescriptorTestShell<T>(ChannelDimension::FourDim) {}
|
||||
|
||||
protected:
|
||||
void SetSizeAndKind() {
|
||||
if (std::is_same_v<uchar4, T>) {
|
||||
this->size = static_cast<int>(sizeof(unsigned char) * 8);
|
||||
this->kind = hipChannelFormatKindUnsigned;
|
||||
} else if (std::is_same_v<char4, T>) {
|
||||
this->size = static_cast<int>(sizeof(signed char) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
} else if (std::is_same_v<ushort4, T>) {
|
||||
this->size = static_cast<int>(sizeof(unsigned short) * 8);
|
||||
this->kind = hipChannelFormatKindUnsigned;
|
||||
} else if (std::is_same_v<short4, T>) {
|
||||
this->size = static_cast<int>(sizeof(signed short) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
} else if (std::is_same_v<uint4, T>) {
|
||||
this->size = static_cast<int>(sizeof(unsigned int) * 8);
|
||||
this->kind = hipChannelFormatKindUnsigned;
|
||||
} else if (std::is_same_v<int4, T>) {
|
||||
this->size = static_cast<int>(sizeof(signed int) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
} else if (std::is_same_v<float4, T>) {
|
||||
this->size = static_cast<int>(sizeof(float) * 8);
|
||||
this->kind = hipChannelFormatKindFloat;
|
||||
} else if (std::is_same_v<ulong4, T>) {
|
||||
this->size = static_cast<int>(sizeof(unsigned long) * 8);
|
||||
this->kind = hipChannelFormatKindUnsigned;
|
||||
} else if (std::is_same_v<long4, T>) {
|
||||
this->size = static_cast<int>(sizeof(signed long) * 8);
|
||||
this->kind = hipChannelFormatKindSigned;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> class ChannelDescriptorTestNone : public ChannelDescriptorTestShell<T> {
|
||||
public:
|
||||
ChannelDescriptorTestNone() : ChannelDescriptorTestShell<T>(ChannelDimension::OneDim) {}
|
||||
|
||||
protected:
|
||||
void SetSizeAndKind() {}
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
# Copyright (c) 2023 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.
|
||||
if(UNIX)
|
||||
set(TEST_SRC ${TEST_SRC}
|
||||
complex_loading_behavior.cc)
|
||||
set(AMD_TEST_SRC
|
||||
hipApiDynamicLoad.cc)
|
||||
|
||||
if(HIP_PLATFORM MATCHES "amd")
|
||||
set(TEST_SRC ${TEST_SRC} ${AMD_TEST_SRC})
|
||||
endif()
|
||||
|
||||
hip_add_exe_to_target(NAME dynamicLoading
|
||||
TEST_SRC ${TEST_SRC}
|
||||
TEST_TARGET_NAME build_tests)
|
||||
|
||||
if(HIP_PLATFORM MATCHES "amd")
|
||||
add_custom_target(libLazyLoad.so COMMAND ${CMAKE_CXX_COMPILER} -fPIC -lpthread -shared ${OFFLOAD_ARCH_STR} ${CMAKE_CURRENT_SOURCE_DIR}/liblazyLoad.cc -I${CMAKE_CURRENT_SOURCE_DIR}/../../include -I${CMAKE_CURRENT_SOURCE_DIR}/../../external/Catch2 -o libLazyLoad.so)
|
||||
elseif(HIP_PLATFORM MATCHES "nvidia")
|
||||
add_custom_target(libLazyLoad.so COMMAND ${CMAKE_CXX_COMPILER} -Xcompiler -fPIC -lpthread -shared ${CMAKE_CURRENT_SOURCE_DIR}/liblazyLoad.cc -I${CMAKE_CURRENT_SOURCE_DIR}/../../include -I${CMAKE_CURRENT_SOURCE_DIR}/../../external/Catch2 -o libLazyLoad.so)
|
||||
endif()
|
||||
|
||||
add_custom_target(bit_extract_kernel.code COMMAND ${CMAKE_CXX_COMPILER} --genco ${OFFLOAD_ARCH_STR} ${CMAKE_CURRENT_SOURCE_DIR}/bit_extract_kernel.cpp -o ${CMAKE_CURRENT_BINARY_DIR}/../dynamicLoading/bit_extract_kernel.code -I${CMAKE_CURRENT_SOURCE_DIR}/../../../../include/ -I${CMAKE_CURRENT_SOURCE_DIR}/../../include)
|
||||
|
||||
if(HIP_PLATFORM MATCHES "amd")
|
||||
hip_add_exe_to_target(NAME Dynamic
|
||||
TEST_SRC ${LINUX_TEST_SRC}
|
||||
TEST_TARGET_NAME build_tests
|
||||
LINKER_LIBS ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
add_dependencies(build_tests bit_extract_kernel.code libLazyLoad.so)
|
||||
endif()
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNNESS 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 INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <hip/hip_runtime.h>
|
||||
extern "C" __global__ void bit_extract_kernel(uint32_t* C_d, const uint32_t*
|
||||
A_d, size_t N) {
|
||||
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
|
||||
size_t stride = blockDim.x * gridDim.x;
|
||||
for (size_t i = offset; i < N; i += stride) {
|
||||
#if HT_AMD
|
||||
C_d[i] = __bitextract_u32(A_d[i], 8, 4);
|
||||
#else /* defined __HIP_PLATFORM_NVIDIA__ or other path */
|
||||
C_d[i] = ((A_d[i] & 0xf00) >> 8);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNNESS 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 INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <hip_test_common.hh>
|
||||
#include <dlfcn.h>
|
||||
#include <hip_test_defgroups.hh>
|
||||
/**
|
||||
* @addtogroup hipLaunchKernelGGL hipLaunchCooperativeKernel
|
||||
* @{
|
||||
* @ingroup DynamicLoading
|
||||
* `hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
|
||||
std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` -
|
||||
* launches Kernel with launch parameters and shared memory on stream with arguments passed
|
||||
* `hipError_t hipLaunchCooperativeKernel(const void* f, dim3 gridDim, dim3 blockDimX,
|
||||
void** kernelParams, unsigned int sharedMemBytes,
|
||||
hipStream_t stream))` -
|
||||
* launches kernel f with launch parameters and shared memory on stream with arguments passed
|
||||
* to kernelparams or extra, where thread blocks can cooperate and synchronize as they execute
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test case to verify locally loaded kernels and dynamically loaded kernels from the library.
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/dynamicLoading/complex_loading_behavior.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.6
|
||||
*/
|
||||
|
||||
__global__ static void vector_add(float* C, float* A, float* B, size_t N) {
|
||||
size_t offset = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
size_t stride = blockDim.x * gridDim.x;
|
||||
for (size_t i = offset; i < N; i += stride) {
|
||||
C[i] = A[i] + B[i];
|
||||
}
|
||||
}
|
||||
|
||||
static bool launch_local_kernel() {
|
||||
bool testResult = true;
|
||||
float *A_d, *B_d, *C_d;
|
||||
float *A_h, *B_h, *C_h;
|
||||
size_t N = 1000000;
|
||||
size_t Nbytes = N * sizeof(float);
|
||||
static int device = 0;
|
||||
|
||||
HIPCHECK(hipSetDevice(device));
|
||||
hipDeviceProp_t props;
|
||||
HIPCHECK(hipGetDeviceProperties(&props, device));
|
||||
|
||||
A_h = reinterpret_cast<float*>(malloc(Nbytes));
|
||||
HIPCHECK(A_h == nullptr ? hipErrorOutOfMemory : hipSuccess);
|
||||
B_h = reinterpret_cast<float*>(malloc(Nbytes));
|
||||
HIPCHECK(B_h == nullptr ? hipErrorOutOfMemory : hipSuccess);
|
||||
C_h = reinterpret_cast<float*>(malloc(Nbytes));
|
||||
HIPCHECK(C_h == nullptr ? hipErrorOutOfMemory : hipSuccess);
|
||||
|
||||
// Fill with Phi + i
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
A_h[i] = 1.618f + i;
|
||||
B_h[i] = 1.618f + i;
|
||||
}
|
||||
|
||||
HIPCHECK(hipMalloc(&A_d, Nbytes));
|
||||
HIPCHECK(hipMalloc(&B_d, Nbytes));
|
||||
HIPCHECK(hipMalloc(&C_d, Nbytes));
|
||||
HIPCHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
|
||||
HIPCHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice));
|
||||
|
||||
const unsigned blocks = 512;
|
||||
const unsigned threadsPerBlock = 256;
|
||||
hipLaunchKernelGGL(vector_add, dim3(blocks), dim3(threadsPerBlock),
|
||||
0, 0, C_d, A_d, B_d, N);
|
||||
HIPCHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
|
||||
|
||||
for (size_t i=0; i < N ; i++) {
|
||||
if (C_h[i] != (A_h[i] + B_h[i])) {
|
||||
testResult = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HIPCHECK(hipFree(A_d));
|
||||
HIPCHECK(hipFree(B_d));
|
||||
HIPCHECK(hipFree(C_d));
|
||||
|
||||
free(A_h);
|
||||
free(B_h);
|
||||
free(C_h);
|
||||
return testResult;
|
||||
}
|
||||
|
||||
static bool launch_dynamically_loaded_kernel() {
|
||||
bool testResult = true;
|
||||
int ret = 1;
|
||||
|
||||
void* handle = dlopen("./libLazyLoad.so", RTLD_LAZY);
|
||||
if (!handle) {
|
||||
INFO("dlopen Error: " << dlerror() << "\n");
|
||||
testResult = false;
|
||||
return testResult;
|
||||
}
|
||||
void* sym = dlsym(handle, "lazyLoad");
|
||||
if (!sym) {
|
||||
INFO("unable to locate lazyLoad within lazyLoad.so\n");
|
||||
dlclose(handle);
|
||||
testResult = false;
|
||||
return testResult;
|
||||
}
|
||||
|
||||
int(*fp)() = reinterpret_cast<int(*)()>(sym);
|
||||
ret = fp();
|
||||
|
||||
if (ret == 0) {
|
||||
testResult = false;
|
||||
}
|
||||
|
||||
dlclose(handle);
|
||||
return testResult;
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_dynamic_loading_device_kernels_from_library") {
|
||||
bool testResult = true;
|
||||
|
||||
testResult &= launch_local_kernel();
|
||||
testResult &= launch_dynamically_loaded_kernel();
|
||||
|
||||
REQUIRE(testResult == true);
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNNESS 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 INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#define fileName "bit_extract_kernel.code"
|
||||
|
||||
#define LEN 64
|
||||
#define SIZE LEN * sizeof(float)
|
||||
|
||||
/**
|
||||
* @addtogroup dyn_hipModuleLoad dyn_hipModuleGetFunction dyn_hipModuleLaunchKernel
|
||||
* @{
|
||||
* @ingroup DynamicLoading
|
||||
* ` hipError_t (*dyn_hipModuleLoad)(hipModule_t*, const char*) = reinterpret_cast
|
||||
<hipError_t (*)(hipModule_t*, const char*)>(sym_hipModuleLoad)` -
|
||||
* Loads code object from file into a module the currrent context
|
||||
* `hipError_t (*dyn_hipModuleGetFunction)(hipFunction_t*, hipModule_t,
|
||||
const char*) = reinterpret_cast < hipError_t (*)(hipFunction_t*,
|
||||
hipModule_t, const char*)>(sym_hipModuleGetFunction)` -
|
||||
* Function with kernelname will be extracted if present in module
|
||||
* `hipError_t (*dyn_hipModuleLaunchKernel)(hipFunction_t, unsigned int,
|
||||
unsigned int, unsigned int, unsigned int, unsigned int,
|
||||
unsigned int, unsigned int, hipStream_t, void**, void**)
|
||||
= reinterpret_cast<hipError_t(*) (hipFunction_t,
|
||||
unsigned int, unsigned int, unsigned int, unsigned int,
|
||||
unsigned int, unsigned int, unsigned int, hipStream_t,
|
||||
void**, void**)>(sym_hipModuleLaunchKernel)` -
|
||||
* launches Kernel with launch parameters and shared memory on stream with arguments passed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test is to load hip runtime using dlopen and get function pointer using dlsym for hip apis.
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/dynamicLoading/hipApiDynamicLoad.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.6
|
||||
*/
|
||||
|
||||
TEST_CASE("Unit_hipApiDynamicLoad") {
|
||||
uint32_t *A_d, *C_d;
|
||||
uint32_t *A_h, *C_h;
|
||||
size_t N = 1000000;
|
||||
size_t Nbytes = N * sizeof(uint32_t);
|
||||
|
||||
void* handle = dlopen("libamdhip64.so", RTLD_LAZY);
|
||||
REQUIRE(handle != NULL);
|
||||
|
||||
void* sym_hipGetDevice = dlsym(handle, "hipGetDevice");
|
||||
void* sym_hipMalloc = dlsym(handle, "hipMalloc");
|
||||
void* sym_hipMemcpyHtoD = dlsym(handle, "hipMemcpyHtoD");
|
||||
void* sym_hipMemcpyDtoH = dlsym(handle, "hipMemcpyDtoH");
|
||||
void* sym_hipModuleLoad = dlsym(handle, "hipModuleLoad");
|
||||
void* sym_hipGetDeviceProperties = dlsym(handle, "hipGetDeviceProperties");
|
||||
void* sym_hipModuleGetFunction = dlsym(handle, "hipModuleGetFunction");
|
||||
void* sym_hipModuleLaunchKernel = dlsym(handle, "hipModuleLaunchKernel");
|
||||
|
||||
dlclose(handle);
|
||||
hipError_t (*dyn_hipGetDevice)(hipDevice_t*, int) = reinterpret_cast
|
||||
<hipError_t (*)(hipDevice_t*, int)>(sym_hipGetDevice);
|
||||
|
||||
hipError_t (*dyn_hipMalloc)(void**, uint32_t) = reinterpret_cast
|
||||
<hipError_t (*)(void**, uint32_t)>(sym_hipMalloc);
|
||||
|
||||
hipError_t (*dyn_hipMemcpyHtoD)(hipDeviceptr_t, void*, size_t) =
|
||||
reinterpret_cast<hipError_t (*)(hipDeviceptr_t, void*,
|
||||
size_t)>(sym_hipMemcpyHtoD);
|
||||
|
||||
hipError_t (*dyn_hipMemcpyDtoH)(void*, hipDeviceptr_t, size_t) =
|
||||
reinterpret_cast<hipError_t (*)(void*, hipDeviceptr_t,
|
||||
size_t)>(sym_hipMemcpyDtoH);
|
||||
|
||||
hipError_t (*dyn_hipModuleLoad)(hipModule_t*, const char*) = reinterpret_cast
|
||||
<hipError_t (*)(hipModule_t*, const char*)>(sym_hipModuleLoad);
|
||||
|
||||
hipError_t (*dyn_hipGetDeviceProperties)(hipDeviceProp_t*, int) =
|
||||
reinterpret_cast<hipError_t (*)(hipDeviceProp_t*, int)>
|
||||
(sym_hipGetDeviceProperties);
|
||||
|
||||
hipError_t (*dyn_hipModuleGetFunction)(hipFunction_t*, hipModule_t,
|
||||
const char*) = reinterpret_cast < hipError_t (*)(hipFunction_t*,
|
||||
hipModule_t, const char*)>(sym_hipModuleGetFunction);
|
||||
|
||||
hipError_t (*dyn_hipModuleLaunchKernel)(hipFunction_t, unsigned int,
|
||||
unsigned int, unsigned int, unsigned int, unsigned int,
|
||||
unsigned int, unsigned int, hipStream_t, void**, void**)
|
||||
= reinterpret_cast<hipError_t(*) (hipFunction_t,
|
||||
unsigned int, unsigned int, unsigned int, unsigned int,
|
||||
unsigned int, unsigned int, unsigned int, hipStream_t,
|
||||
void**, void**)>(sym_hipModuleLaunchKernel);
|
||||
|
||||
hipDevice_t device;
|
||||
HIPCHECK(dyn_hipGetDevice(&device, 0));
|
||||
|
||||
hipDeviceProp_t props;
|
||||
HIPCHECK(dyn_hipGetDeviceProperties(&props, device));
|
||||
A_h = reinterpret_cast<uint32_t*>(malloc(Nbytes));
|
||||
REQUIRE(A_h != NULL);
|
||||
C_h = reinterpret_cast<uint32_t*>(malloc(Nbytes));
|
||||
REQUIRE(C_h != NULL);
|
||||
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
A_h[i] = i;
|
||||
}
|
||||
|
||||
HIPCHECK(dyn_hipMalloc(reinterpret_cast<void**>(&A_d), Nbytes));
|
||||
HIPCHECK(dyn_hipMalloc(reinterpret_cast<void**>(&C_d), Nbytes));
|
||||
|
||||
HIPCHECK(dyn_hipMemcpyHtoD((hipDeviceptr_t)(A_d), A_h, Nbytes));
|
||||
|
||||
struct {
|
||||
void* _Cd;
|
||||
void* _Ad;
|
||||
size_t _N;
|
||||
} args;
|
||||
args._Cd = reinterpret_cast<void**> (C_d);
|
||||
args._Ad = reinterpret_cast<void**> (A_d);
|
||||
args._N = static_cast<size_t> (N);
|
||||
size_t size = sizeof(args);
|
||||
|
||||
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args,
|
||||
HIP_LAUNCH_PARAM_BUFFER_SIZE, &size, HIP_LAUNCH_PARAM_END};
|
||||
|
||||
hipModule_t Module;
|
||||
HIPCHECK(dyn_hipModuleLoad(&Module, fileName));
|
||||
|
||||
hipFunction_t Function;
|
||||
HIPCHECK(dyn_hipModuleGetFunction(&Function, Module, "bit_extract_kernel"));
|
||||
|
||||
HIPCHECK(dyn_hipModuleLaunchKernel(Function, 1, 1, 1, LEN, 1, 1, 0, 0, NULL,
|
||||
reinterpret_cast<void**>(&config)));
|
||||
|
||||
HIPCHECK(dyn_hipMemcpyDtoH(C_h, (hipDeviceptr_t)(C_d), Nbytes));
|
||||
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
unsigned Agold = ((A_h[i] & 0xf00) >> 8);
|
||||
REQUIRE(C_h[i] == Agold);
|
||||
}
|
||||
HIPCHECK(hipFree(A_d));
|
||||
HIPCHECK(hipFree(C_d));
|
||||
free(A_h);
|
||||
free(C_h);
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNNESS 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 INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <hip/hip_runtime_api.h>
|
||||
|
||||
#define CHECK_RET_VAL(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);\
|
||||
}\
|
||||
}
|
||||
|
||||
__global__ static void addition(float* C, float* A, float* B, size_t N) {
|
||||
size_t offset = hipBlockIdx_x * hipBlockDim_x + hipThreadIdx_x;
|
||||
size_t stride = hipBlockDim_x * hipGridDim_x;
|
||||
|
||||
for (size_t i = offset; i < N; i += stride) {
|
||||
C[i] = A[i] + B[i];
|
||||
}
|
||||
}
|
||||
|
||||
static int vectorAddKernelTest() {
|
||||
int testResult = 1;
|
||||
float *A_d, *B_d, *C_d;
|
||||
float *A_h, *B_h, *C_h;
|
||||
size_t N = 1000000;
|
||||
size_t Nbytes = N * sizeof(float);
|
||||
static int device = 0;
|
||||
|
||||
CHECK_RET_VAL(hipSetDevice(device));
|
||||
hipDeviceProp_t props;
|
||||
CHECK_RET_VAL(hipGetDeviceProperties(&props, device));
|
||||
A_h = reinterpret_cast<float*>(malloc(Nbytes));
|
||||
CHECK_RET_VAL(A_h == nullptr ? hipErrorOutOfMemory : hipSuccess);
|
||||
B_h = reinterpret_cast<float*>(malloc(Nbytes));
|
||||
CHECK_RET_VAL(B_h == nullptr ? hipErrorOutOfMemory : hipSuccess);
|
||||
C_h = reinterpret_cast<float*>(malloc(Nbytes));
|
||||
CHECK_RET_VAL(C_h == nullptr ? hipErrorOutOfMemory : hipSuccess);
|
||||
|
||||
// Fill with Phi + i
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
A_h[i] = 1.618f + i;
|
||||
B_h[i] = 1.618f + i;
|
||||
}
|
||||
|
||||
CHECK_RET_VAL(hipMalloc(&A_d, Nbytes));
|
||||
CHECK_RET_VAL(hipMalloc(&B_d, Nbytes));
|
||||
CHECK_RET_VAL(hipMalloc(&C_d, Nbytes));
|
||||
CHECK_RET_VAL(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
|
||||
CHECK_RET_VAL(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice));
|
||||
|
||||
const unsigned blocks = 512;
|
||||
const unsigned threadsPerBlock = 256;
|
||||
hipLaunchKernelGGL(addition, dim3(blocks), dim3(threadsPerBlock),
|
||||
0, 0, C_d, A_d, B_d, N);
|
||||
CHECK_RET_VAL(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
|
||||
|
||||
for (size_t i=0; i < N ; i++) {
|
||||
if (C_h[i] != (A_h[i] + B_h[i])) {
|
||||
testResult = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_RET_VAL(hipFree(A_d));
|
||||
CHECK_RET_VAL(hipFree(B_d));
|
||||
CHECK_RET_VAL(hipFree(C_d));
|
||||
|
||||
free(A_h);
|
||||
free(B_h);
|
||||
free(C_h);
|
||||
return testResult;
|
||||
}
|
||||
|
||||
#include "hip/hip_cooperative_groups.h"
|
||||
|
||||
namespace cg = cooperative_groups;
|
||||
|
||||
static const uint BufferSizeInDwords = 448 * 1024 * 1024;
|
||||
|
||||
__global__ static void test_gws(uint* buf, uint bufSize,
|
||||
int64_t* tmpBuf, int64_t* result) {
|
||||
extern __shared__ int64_t tmp[];
|
||||
uint offset = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
uint stride = gridDim.x * blockDim.x;
|
||||
cg::grid_group gg = cg::this_grid();
|
||||
|
||||
int64_t sum = 0;
|
||||
|
||||
for (uint i = offset; i < bufSize; i += stride) {
|
||||
sum += buf[i];
|
||||
}
|
||||
|
||||
tmp[threadIdx.x] = sum;
|
||||
__syncthreads();
|
||||
|
||||
if (threadIdx.x == 0) {
|
||||
sum = 0;
|
||||
for (uint i = 0; i < blockDim.x; i++) {
|
||||
sum += tmp[i];
|
||||
}
|
||||
tmpBuf[blockIdx.x] = sum;
|
||||
}
|
||||
|
||||
gg.sync();
|
||||
|
||||
if (offset == 0) {
|
||||
for (uint i = 1; i < gridDim.x; ++i) {
|
||||
sum += tmpBuf[i];
|
||||
}
|
||||
*result = sum;
|
||||
}
|
||||
}
|
||||
|
||||
static int cooperativeKernelTest() {
|
||||
int testResult = 1;
|
||||
uint* dA;
|
||||
int64_t* dB;
|
||||
int64_t* dC;
|
||||
int64_t* Ah;
|
||||
|
||||
hipDeviceProp_t deviceProp;
|
||||
hipGetDeviceProperties(&deviceProp, 0);
|
||||
|
||||
if (!deviceProp.cooperativeLaunch) {
|
||||
return testResult;
|
||||
}
|
||||
|
||||
uint32_t* init = new uint32_t[BufferSizeInDwords];
|
||||
|
||||
for (uint32_t i = 0; i < BufferSizeInDwords; ++i) {
|
||||
init[i] = i;
|
||||
}
|
||||
size_t SIZE = BufferSizeInDwords * sizeof(uint);
|
||||
|
||||
CHECK_RET_VAL(hipMalloc(reinterpret_cast<void**>(&dA), SIZE));
|
||||
CHECK_RET_VAL(hipMalloc(reinterpret_cast<void**>(&dC), sizeof(int64_t)));
|
||||
CHECK_RET_VAL(hipMemcpy(dA, init, SIZE, hipMemcpyHostToDevice));
|
||||
Ah = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
|
||||
|
||||
hipStream_t stream;
|
||||
CHECK_RET_VAL(hipStreamCreate(&stream));
|
||||
|
||||
dim3 dimBlock = dim3(1);
|
||||
dim3 dimGrid = dim3(1);
|
||||
|
||||
int numBlocks = 0;
|
||||
uint workgroups[4] = {32, 64, 128, 256};
|
||||
|
||||
for (uint i = 0; i < 4; ++i) {
|
||||
dimBlock.x = workgroups[i];
|
||||
/* Calculate the device occupancy to know how many blocks can be
|
||||
run concurrently */
|
||||
hipOccupancyMaxActiveBlocksPerMultiprocessor(&numBlocks,
|
||||
test_gws, dimBlock.x * dimBlock.y * dimBlock.z, dimBlock.x *
|
||||
sizeof(int64_t));
|
||||
dimGrid.x = deviceProp.multiProcessorCount * std::min(numBlocks, 32);
|
||||
CHECK_RET_VAL(hipMalloc(reinterpret_cast<void**>(&dB),
|
||||
dimGrid.x * sizeof(int64_t)));
|
||||
|
||||
void *params[4];
|
||||
params[0] = reinterpret_cast<void*>(&dA);
|
||||
params[1] = (void*)(&BufferSizeInDwords); // NOLINT
|
||||
params[2] = reinterpret_cast<void*>(&dB);
|
||||
params[3] = reinterpret_cast<void*>(&dC);
|
||||
|
||||
CHECK_RET_VAL(hipLaunchCooperativeKernel(reinterpret_cast<void*>(test_gws),
|
||||
dimGrid, dimBlock, params,
|
||||
dimBlock.x * sizeof(int64_t), stream));
|
||||
|
||||
CHECK_RET_VAL(hipMemcpy(Ah, dC, sizeof(int64_t), hipMemcpyDeviceToHost));
|
||||
|
||||
if (*Ah != (((int64_t)(BufferSizeInDwords) * (BufferSizeInDwords - 1))
|
||||
/ 2)) {
|
||||
CHECK_RET_VAL(hipFree(dB));
|
||||
testResult = 0;
|
||||
break;
|
||||
|
||||
} else {
|
||||
CHECK_RET_VAL(hipFree(dB));
|
||||
}
|
||||
}
|
||||
CHECK_RET_VAL(hipStreamDestroy(stream));
|
||||
CHECK_RET_VAL(hipFree(dC));
|
||||
CHECK_RET_VAL(hipFree(dA));
|
||||
delete [] init;
|
||||
free(Ah);
|
||||
return testResult;
|
||||
}
|
||||
|
||||
extern "C" int lazyLoad() {
|
||||
return vectorAddKernelTest() & cooperativeKernelTest();
|
||||
}
|
||||
@@ -158,7 +158,9 @@ TEST_CASE("Unit_hipEventElapsedTime_NotReady_Negative") {
|
||||
// Record start event
|
||||
HIP_CHECK(hipEventRecord(start, nullptr));
|
||||
|
||||
HipTest::runKernelForDuration(std::chrono::milliseconds(1000));
|
||||
HipTest::BlockingContext b_context{nullptr};
|
||||
b_context.block_stream(); // blocked stream
|
||||
REQUIRE(b_context.is_blocked());
|
||||
|
||||
// Record stop event
|
||||
HIP_CHECK(hipEventRecord(stop, nullptr));
|
||||
@@ -166,7 +168,8 @@ TEST_CASE("Unit_hipEventElapsedTime_NotReady_Negative") {
|
||||
// stop event has not been completed
|
||||
float tElapsed = 1.0f;
|
||||
HIP_CHECK_ERROR(hipEventQuery(stop), hipErrorNotReady);
|
||||
HIP_ASSERT(hipEventElapsedTime(&tElapsed,start,stop) == hipErrorNotReady);
|
||||
HIP_ASSERT(hipEventElapsedTime(&tElapsed, start, stop) == hipErrorNotReady);
|
||||
b_context.unblock_stream();
|
||||
|
||||
HIP_CHECK(hipStreamSynchronize(nullptr));
|
||||
HIP_CHECK(hipEventDestroy(start));
|
||||
|
||||
@@ -19,57 +19,6 @@ THE SOFTWARE.
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
|
||||
/**
|
||||
* @addtogroup hipEventQuery hipEventQuery
|
||||
* @{
|
||||
* @ingroup EventTest
|
||||
* `hipEventQuery(hipEvent_t event)` -
|
||||
* Query the status of the specified event.
|
||||
* ________________________
|
||||
* Test cases from other modules:
|
||||
* - @ref Unit_hipEventIpc
|
||||
*/
|
||||
|
||||
// Since we can not use atomic*_system on every gpu, we will use wait based on clock rate.
|
||||
// This wont be accurate since current clock rate of a GPU varies depending on many variables
|
||||
// including thermals, load, utilization etc
|
||||
__global__ void waitKernel(int clockRate, int seconds) {
|
||||
auto start = clock();
|
||||
auto ms = seconds * 1000;
|
||||
long long waitTill = clockRate * (long long)ms;
|
||||
while (1) {
|
||||
auto end = clock();
|
||||
if ((end - start) > waitTill) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__global__ void waitKernel_gfx11(int clockRate, int seconds) {
|
||||
#if HT_AMD
|
||||
auto start = wall_clock64();
|
||||
auto ms = seconds * 1000;
|
||||
long long waitTill = clockRate * (long long)ms;
|
||||
while (1) {
|
||||
auto end = wall_clock64();
|
||||
if ((end - start) > waitTill) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Query events with a single and with multiple devices.
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/event/Unit_hipEventQuery.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEST_CASE("Unit_hipEventQuery_DifferentDevice") {
|
||||
hipEvent_t event1{}, event2{};
|
||||
HIP_CHECK(hipEventCreate(&event1));
|
||||
@@ -81,19 +30,14 @@ TEST_CASE("Unit_hipEventQuery_DifferentDevice") {
|
||||
HIP_CHECK(hipStreamCreate(&stream));
|
||||
REQUIRE(stream != nullptr);
|
||||
|
||||
hipDeviceProp_t prop{};
|
||||
HIP_CHECK(hipGetDeviceProperties(&prop, 0));
|
||||
auto clockRate = prop.clockRate;
|
||||
|
||||
// Start kernel on 1st device
|
||||
HipTest::BlockingContext b_context1{stream}; // og context
|
||||
// Block stream
|
||||
{
|
||||
HIP_CHECK(hipSetDevice(0));
|
||||
HIP_CHECK(hipEventRecord(event1, stream));
|
||||
|
||||
auto waitKernel_used = IsGfx11() ? waitKernel_gfx11 : waitKernel;
|
||||
// Start kernel and wait for 3 seconds
|
||||
// Make sure you increase this time if you add more tests here
|
||||
waitKernel_used<<<1, 1, 0, stream>>>(clockRate, 3);
|
||||
b_context1.block_stream(); // blocked stream
|
||||
REQUIRE(b_context1.is_blocked());
|
||||
|
||||
HIP_CHECK(hipEventRecord(event2, stream));
|
||||
|
||||
@@ -101,7 +45,7 @@ TEST_CASE("Unit_hipEventQuery_DifferentDevice") {
|
||||
HIP_CHECK(hipEventQuery(event1)); // Should be done
|
||||
|
||||
HIP_CHECK_ERROR(hipEventQuery(event2),
|
||||
hipErrorNotReady); // Wont be done since kernel is waiting
|
||||
hipErrorNotReady); // Wont be done since stream is blocked
|
||||
}
|
||||
|
||||
// If other devices are available, set it
|
||||
@@ -114,8 +58,8 @@ TEST_CASE("Unit_hipEventQuery_DifferentDevice") {
|
||||
HIP_CHECK(hipEventQuery(event1));
|
||||
HIP_CHECK_ERROR(hipEventQuery(event2), hipErrorNotReady);
|
||||
|
||||
// Sync
|
||||
// if it hangs here it means GPU kernel cant see the value update by atomic store
|
||||
b_context1.unblock_stream();
|
||||
|
||||
HIP_CHECK(hipEventSynchronize(event2));
|
||||
|
||||
// Query, should be done now
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
set(TEST_SRC
|
||||
execution_control_common.cc
|
||||
hipFuncSetCacheConfig.cc
|
||||
hipFuncSetSharedMemConfig.cc
|
||||
hipFuncSetAttribute.cc
|
||||
)
|
||||
|
||||
hip_add_exe_to_target(NAME ExecutionControlTest
|
||||
TEST_SRC ${TEST_SRC}
|
||||
TEST_TARGET_NAME build_tests
|
||||
COMPILE_OPTIONS -std=c++17)
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
Copyright (c) 2022 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 "execution_control_common.hh"
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
|
||||
__global__ void kernel() {}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright (c) 2022 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
__global__ void kernel();
|
||||
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
Copyright (c) 2022 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 "execution_control_common.hh"
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip/hip_runtime_api.h>
|
||||
|
||||
/**
|
||||
* @addtogroup hipFuncSetAttribute hipFuncSetAttribute
|
||||
* @{
|
||||
* @ingroup ExecutionTest
|
||||
* `hipFuncSetAttribute(const void* func, hipFuncAttribute attr, int value)` -
|
||||
* Set attribute for a specific function.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Sets maximum dynamic shared memory size to the non-default value.
|
||||
* - Expected output: return `hipSuccess`
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/executionControl/hipFuncSetAttribute.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEST_CASE("Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize") {
|
||||
HIP_CHECK(hipFuncSetAttribute(reinterpret_cast<void*>(kernel),
|
||||
hipFuncAttributeMaxDynamicSharedMemorySize, 1024));
|
||||
|
||||
hipFuncAttributes attributes;
|
||||
HIP_CHECK(hipFuncGetAttributes(&attributes, reinterpret_cast<void*>(kernel)));
|
||||
|
||||
REQUIRE(attributes.maxDynamicSharedSizeBytes == 1024);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Sets preferred shared memory carveout to the non-default value.
|
||||
* - Expected output: return `hipSuccess`
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/executionControl/hipFuncSetAttribute.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEST_CASE("Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout") {
|
||||
HIP_CHECK(hipFuncSetAttribute(reinterpret_cast<void*>(kernel),
|
||||
hipFuncAttributePreferredSharedMemoryCarveout, 50));
|
||||
|
||||
hipFuncAttributes attributes;
|
||||
HIP_CHECK(hipFuncGetAttributes(&attributes, reinterpret_cast<void*>(kernel)));
|
||||
|
||||
REQUIRE(attributes.preferredShmemCarveout == 50);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Validates handling of valid arguments:
|
||||
* -# When `hipFuncAttributeMaxDynamicSharedMemorySize == 0`
|
||||
* - Expected output: return `hipSuccess`
|
||||
* -# When `hipFuncAttributeMaxDynamicSharedMemorySize == maxSharedMemoryPerBlock - sharedSizeBytes`
|
||||
* - Expected output: return `hipSuccess`
|
||||
* -# When `hipFuncAttributePreferredSharedMemoryCarveout` is 0%
|
||||
* - Expected output: return `hipSuccess`
|
||||
* -# When `hipFuncAttributePreferredSharedMemoryCarveout` is 100%
|
||||
* - Expected output: return `hipSuccess`
|
||||
* -# When `hipFuncAttributePreferredSharedMemoryCarveout` is default (-1)
|
||||
* - Expected output: return `hipSuccess`
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/executionControl/hipFuncSetAttribute.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEST_CASE("Unit_hipFuncSetAttribute_Positive_Parameters") {
|
||||
SECTION("hipFuncAttributeMaxDynamicSharedMemorySize == 0") {
|
||||
HIP_CHECK(hipFuncSetAttribute(reinterpret_cast<void*>(kernel),
|
||||
hipFuncAttributeMaxDynamicSharedMemorySize, 0));
|
||||
}
|
||||
|
||||
SECTION(
|
||||
"hipFuncAttributeMaxDynamicSharedMemorySize == maxSharedMemoryPerBlock - sharedSizeBytes") {
|
||||
// The sum of this value and the function attribute sharedSizeBytes cannot exceed the device
|
||||
// attribute cudaDevAttrMaxSharedMemoryPerBlockOptin
|
||||
int max_shared;
|
||||
HIP_CHECK(hipDeviceGetAttribute(&max_shared, hipDeviceAttributeMaxSharedMemoryPerBlock, 0));
|
||||
|
||||
hipFuncAttributes attributes;
|
||||
HIP_CHECK(hipFuncGetAttributes(&attributes, reinterpret_cast<void*>(kernel)));
|
||||
|
||||
HIP_CHECK(hipFuncSetAttribute(reinterpret_cast<void*>(kernel),
|
||||
hipFuncAttributeMaxDynamicSharedMemorySize,
|
||||
max_shared - attributes.sharedSizeBytes));
|
||||
}
|
||||
|
||||
SECTION("hipFuncAttributePreferredSharedMemoryCarveout == 0") {
|
||||
HIP_CHECK(hipFuncSetAttribute(reinterpret_cast<void*>(kernel),
|
||||
hipFuncAttributePreferredSharedMemoryCarveout, 0));
|
||||
}
|
||||
|
||||
SECTION("hipFuncAttributePreferredSharedMemoryCarveout == 100") {
|
||||
HIP_CHECK(hipFuncSetAttribute(reinterpret_cast<void*>(kernel),
|
||||
hipFuncAttributePreferredSharedMemoryCarveout, 100));
|
||||
}
|
||||
|
||||
SECTION("hipFuncAttributePreferredSharedMemoryCarveout == -1 (default)") {
|
||||
HIP_CHECK(hipFuncSetAttribute(reinterpret_cast<void*>(kernel),
|
||||
hipFuncAttributePreferredSharedMemoryCarveout, -1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Validates handling of invalid arguments:
|
||||
* -# When pointer to the kernel function is `nullptr`
|
||||
* - Expected output: return `hipErrorInvalidDeviceFunction`
|
||||
* -# When the attribute is invalid
|
||||
* - Expected output: return `hipErrorInvalidValue`
|
||||
* -# When `hipFuncAttributeMaxDynamicSharedMemorySize < 0`
|
||||
* - Expected output: return `hipErrorInvalidValue`
|
||||
* -# When `hipFuncAttributeMaxDynamicSharedMemorySize > maxSharedMemoryPerBlock - sharedSizeBytes`
|
||||
* - Expected output: return `hipErrorInvalidValue`
|
||||
* -# When `hipFuncAttributePreferredSharedMemoryCarveout` is negative
|
||||
* - Expected output: return `hipErrorInvalidValue`
|
||||
* -# When `hipFuncAttributePreferredSharedMemoryCarveout` is above 100%
|
||||
* - Expected output: return `hipErrorInvalidValue`
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/executionControl/hipFuncSetAttribute.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEST_CASE("Unit_hipFuncSetAttribute_Negative_Parameters") {
|
||||
SECTION("func == nullptr") {
|
||||
HIP_CHECK_ERROR(hipFuncSetAttribute(nullptr, hipFuncAttributePreferredSharedMemoryCarveout, 50),
|
||||
hipErrorInvalidDeviceFunction);
|
||||
}
|
||||
|
||||
SECTION("invalid attribute") {
|
||||
HIP_CHECK_ERROR(
|
||||
hipFuncSetAttribute(reinterpret_cast<void*>(kernel), static_cast<hipFuncAttribute>(-1), 50),
|
||||
hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
SECTION("hipFuncAttributeMaxDynamicSharedMemorySize < 0") {
|
||||
HIP_CHECK_ERROR(hipFuncSetAttribute(reinterpret_cast<void*>(kernel),
|
||||
hipFuncAttributeMaxDynamicSharedMemorySize, -1),
|
||||
hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
SECTION(
|
||||
"hipFuncAttributeMaxDynamicSharedMemorySize > maxSharedMemoryPerBlock - sharedSizeBytes") {
|
||||
// The sum of this value and the function attribute sharedSizeBytes cannot exceed the device
|
||||
// attribute cudaDevAttrMaxSharedMemoryPerBlockOptin
|
||||
int max_shared;
|
||||
HIP_CHECK(hipDeviceGetAttribute(&max_shared, hipDeviceAttributeMaxSharedMemoryPerBlock, 0));
|
||||
|
||||
hipFuncAttributes attributes;
|
||||
HIP_CHECK(hipFuncGetAttributes(&attributes, reinterpret_cast<void*>(kernel)));
|
||||
|
||||
HIP_CHECK_ERROR(hipFuncSetAttribute(reinterpret_cast<void*>(kernel),
|
||||
hipFuncAttributeMaxDynamicSharedMemorySize,
|
||||
max_shared - attributes.sharedSizeBytes + 1),
|
||||
hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
SECTION("hipFuncAttributePreferredSharedMemoryCarveout < -1") {
|
||||
HIP_CHECK_ERROR(hipFuncSetAttribute(reinterpret_cast<void*>(kernel),
|
||||
hipFuncAttributePreferredSharedMemoryCarveout, -2),
|
||||
hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
SECTION("hipFuncAttributePreferredSharedMemoryCarveout > 100") {
|
||||
HIP_CHECK_ERROR(hipFuncSetAttribute(reinterpret_cast<void*>(kernel),
|
||||
hipFuncAttributePreferredSharedMemoryCarveout, 101),
|
||||
hipErrorInvalidValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Sets `hipFuncAttributeMaxDynamicSharedMemorySize` to the non-supported value
|
||||
* - Expected output: return `hipErrorNotSupported`
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/executionControl/hipFuncSetAttribute.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - Platform specific (AMD)
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEST_CASE("Unit_hipFuncSetAttribute_Positive_MaxDynamicSharedMemorySize_Not_Supported") {
|
||||
hipFuncAttributes old_attributes;
|
||||
HIP_CHECK(hipFuncGetAttributes(&old_attributes, reinterpret_cast<void*>(kernel)));
|
||||
|
||||
HIP_CHECK_ERROR(hipFuncSetAttribute(reinterpret_cast<void*>(kernel),
|
||||
hipFuncAttributeMaxDynamicSharedMemorySize, 1024),
|
||||
hipErrorNotSupported);
|
||||
|
||||
hipFuncAttributes new_attributes;
|
||||
HIP_CHECK(hipFuncGetAttributes(&new_attributes, reinterpret_cast<void*>(kernel)));
|
||||
|
||||
REQUIRE(old_attributes.maxDynamicSharedSizeBytes == new_attributes.maxDynamicSharedSizeBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Sets `hipFuncAttributePreferredSharedMemoryCarveout` to the non-supported value
|
||||
* - Expected output: return `hipErrorNotSupported`
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/executionControl/hipFuncSetAttribute.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - Platform specific (AMD)
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEST_CASE("Unit_hipFuncSetAttribute_Positive_PreferredSharedMemoryCarveout_Not_Supported") {
|
||||
hipFuncAttributes old_attributes;
|
||||
HIP_CHECK(hipFuncGetAttributes(&old_attributes, reinterpret_cast<void*>(kernel)));
|
||||
|
||||
HIP_CHECK_ERROR(hipFuncSetAttribute(reinterpret_cast<void*>(kernel),
|
||||
hipFuncAttributePreferredSharedMemoryCarveout, 50),
|
||||
hipErrorNotSupported);
|
||||
|
||||
hipFuncAttributes new_attributes;
|
||||
HIP_CHECK(hipFuncGetAttributes(&new_attributes, reinterpret_cast<void*>(kernel)));
|
||||
|
||||
REQUIRE(old_attributes.preferredShmemCarveout == new_attributes.preferredShmemCarveout);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
Copyright (c) 2022 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 "execution_control_common.hh"
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip/hip_runtime_api.h>
|
||||
|
||||
/**
|
||||
* @addtogroup hipFuncSetCacheConfig hipFuncSetCacheConfig
|
||||
* @{
|
||||
* @ingroup ExecutionTest
|
||||
* `hipFuncSetCacheConfig(const void* func, hipFuncCache_t config)` -
|
||||
* Set Cache configuration for a specific function.
|
||||
*/
|
||||
|
||||
namespace {
|
||||
constexpr std::array<hipFuncCache_t, 4> kCacheConfigs{
|
||||
hipFuncCachePreferNone, hipFuncCachePreferShared, hipFuncCachePreferL1,
|
||||
hipFuncCachePreferEqual};
|
||||
} // anonymous namespace
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Sets cache config for every cache config enumeration.
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/executionControl/hipFuncSetCacheConfig.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEST_CASE("Unit_hipFuncSetCacheConfig_Positive_Basic") {
|
||||
const auto cache_config = GENERATE(from_range(begin(kCacheConfigs), end(kCacheConfigs)));
|
||||
|
||||
HIP_CHECK(hipFuncSetCacheConfig(reinterpret_cast<void*>(kernel), cache_config));
|
||||
|
||||
kernel<<<1, 1>>>();
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Validates handling of invalid arguments:
|
||||
* -# When pointer to the kernel function is `nullptr`
|
||||
* - Expected output: return `hipErrorInvalidDeviceFunction`
|
||||
* -# When cache config enumeration is invalid
|
||||
* - Expected output: return `hipErrorInvalidValue`
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/executionControl/hipFuncSetCacheConfig.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEST_CASE("Unit_hipFuncSetCacheConfig_Negative_Parameters") {
|
||||
SECTION("func == nullptr") {
|
||||
HIP_CHECK_ERROR(hipFuncSetCacheConfig(nullptr, hipFuncCachePreferNone),
|
||||
hipErrorInvalidDeviceFunction);
|
||||
}
|
||||
SECTION("invalid cache config") {
|
||||
HIP_CHECK_ERROR(
|
||||
hipFuncSetCacheConfig(reinterpret_cast<void*>(kernel), static_cast<hipFuncCache_t>(-1)),
|
||||
hipErrorInvalidValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Sets cache config that is not supported.
|
||||
* - Expected output: return `hipErrorNotSupported`
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/executionControl/hipFuncSetCacheConfig.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - Platform specific (AMD)
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEST_CASE("Unit_hipFuncSetCacheConfig_Negative_Not_Supported") {
|
||||
HIP_CHECK_ERROR(hipFuncSetCacheConfig(reinterpret_cast<void*>(kernel), hipFuncCachePreferNone),
|
||||
hipErrorNotSupported);
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
Copyright (c) 2022 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 "execution_control_common.hh"
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip/hip_runtime_api.h>
|
||||
|
||||
/**
|
||||
* @addtogroup hipFuncSetSharedMemConfig hipFuncSetSharedMemConfig
|
||||
* @{
|
||||
* @ingroup ExecutionTest
|
||||
* `hipFuncSetSharedMemConfig(const void* func, hipSharedMemConfig config)` -
|
||||
* Set shared memory configuation for a specific function.
|
||||
*/
|
||||
|
||||
namespace {
|
||||
constexpr std::array<hipSharedMemConfig, 3> kSharedMemConfigs{
|
||||
hipSharedMemBankSizeDefault, hipSharedMemBankSizeFourByte, hipSharedMemBankSizeEightByte};
|
||||
} // anonymous namespace
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Sets cache config for every shared memory config enumeration.
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/executionControl/hipFuncSetSharedMemConfig.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEST_CASE("Unit_hipFuncSetSharedMemConfig_Positive_Basic") {
|
||||
const auto shared_mem_config =
|
||||
GENERATE(from_range(begin(kSharedMemConfigs), end(kSharedMemConfigs)));
|
||||
|
||||
HIP_CHECK(hipFuncSetSharedMemConfig(reinterpret_cast<void*>(kernel), shared_mem_config));
|
||||
|
||||
kernel<<<1, 1>>>();
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Validates handling of invalid arguments:
|
||||
* -# When pointer to the kernel function is `nullptr`
|
||||
* - Expected output: return `hipErrorInvalidDeviceFunction`
|
||||
* -# When shared memory config enumeration is invalid
|
||||
* - Expected output: return `hipErrorInvalidValue`
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/executionControl/hipFuncSetSharedMemConfig.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEST_CASE("Unit_hipFuncSetSharedMemConfig_Negative_Parameters") {
|
||||
SECTION("func == nullptr") {
|
||||
HIP_CHECK_ERROR(hipFuncSetSharedMemConfig(nullptr, hipSharedMemBankSizeDefault),
|
||||
hipErrorInvalidDeviceFunction);
|
||||
}
|
||||
SECTION("invalid shared mem config") {
|
||||
HIP_CHECK_ERROR(hipFuncSetSharedMemConfig(reinterpret_cast<void*>(kernel),
|
||||
static_cast<hipSharedMemConfig>(-1)),
|
||||
hipErrorInvalidValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Sets shared memory config that is not supported.
|
||||
* - Expected output: return `hipErrorNotSupported`
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - unit/executionControl/hipFuncSetSharedMemConfig.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - Platform specific (AMD)
|
||||
* - HIP_VERSION >= 5.2
|
||||
*/
|
||||
TEST_CASE("Unit_hipFuncSetSharedMemConfig_Negative_Not_Supported") {
|
||||
HIP_CHECK_ERROR(
|
||||
hipFuncSetSharedMemConfig(reinterpret_cast<void*>(kernel), hipSharedMemBankSizeDefault),
|
||||
hipErrorNotSupported);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
# AMD specific test
|
||||
if(HIP_PLATFORM MATCHES "amd")
|
||||
if(UNIX)
|
||||
set(TEST_SRC
|
||||
hipMalloc.cc
|
||||
)
|
||||
# Creating Custom object file
|
||||
add_custom_target(malloc_custom COMMAND g++ -c ${CMAKE_CURRENT_SOURCE_DIR}/hipMalloc.cpp -I${HIP_PATH}/include -D__HIP_PLATFORM_AMD__ -o malloc.o BYPRODUCTS malloc.o)
|
||||
add_library(malloc_gpp OBJECT IMPORTED)
|
||||
set_property(TARGET malloc_gpp PROPERTY IMPORTED_OBJECTS "${CMAKE_CURRENT_BINARY_DIR}/malloc.o")
|
||||
|
||||
hip_add_exe_to_target(NAME gppTests
|
||||
TEST_SRC ${TEST_SRC}
|
||||
TEST_TARGET_NAME build_tests
|
||||
LINKER_LIBS malloc_gpp)
|
||||
|
||||
add_dependencies(gppTests malloc_custom)
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INNCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANNY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
* */
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
#include "hipMalloc.h"
|
||||
/**
|
||||
* @addtogroup hipMalloc hipMalloc
|
||||
* @{
|
||||
* @ingroup MemoryTest
|
||||
* `hipError_t hipMalloc(void** ptr, size_t size)` -
|
||||
* Allocate memory on the default accelerator.
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Allocate memory by using hipMalloc API and verify hipSuccess is returned.
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/g++/hipMalloc.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.6
|
||||
*/
|
||||
|
||||
TEST_CASE("Unit_hipMalloc_gpptest") {
|
||||
printf("calling cpp function from here\n");
|
||||
int result = MallocFunc();
|
||||
REQUIRE(result == 1);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2019 - 2021 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INNCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANNY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
* */
|
||||
|
||||
#include <hip/hip_runtime_api.h>
|
||||
#include <iostream>
|
||||
#include "hipMalloc.h"
|
||||
|
||||
int MallocFunc() {
|
||||
int* Ad;
|
||||
hipError_t err;
|
||||
err = hipMalloc(reinterpret_cast<void**>(&Ad), 1024);
|
||||
if (err == hipSuccess) {
|
||||
std::cout <<"PASSED!" <<std::endl;
|
||||
return 1;
|
||||
} else {
|
||||
std::cout <<"FAILED!" <<std::endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INNCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANNY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
* */
|
||||
|
||||
#include <iostream>
|
||||
|
||||
extern int MallocFunc();
|
||||
@@ -130,6 +130,8 @@ set(TEST_SRC
|
||||
hipGraphKernelNodeGetAttribute.cc
|
||||
hipGraphKernelNodeSetAttribute.cc)
|
||||
|
||||
add_custom_target(add_Kernel.code COMMAND ${CMAKE_CXX_COMPILER} --genco ${OFFLOAD_ARCH_STR} ${CMAKE_CURRENT_SOURCE_DIR}/add_Kernel.cpp -o ${CMAKE_CURRENT_BINARY_DIR}/../graph/add_Kernel.code -I${CMAKE_CURRENT_SOURCE_DIR}/../../../../include/ -I${CMAKE_CURRENT_SOURCE_DIR}/../../include --rocm-path=${ROCM_PATH})
|
||||
|
||||
hip_add_exe_to_target(NAME GraphsTest2
|
||||
TEST_SRC ${TEST_SRC}
|
||||
TEST_TARGET_NAME build_tests)
|
||||
@@ -138,3 +140,5 @@ if(HIP_PLATFORM MATCHES "amd")
|
||||
add_custom_target(hipMatMul COMMAND ${CMAKE_CXX_COMPILER} --genco ${OFFLOAD_ARCH_STR} ${CMAKE_CURRENT_SOURCE_DIR}/hipMatMul.cc -o ${CMAKE_CURRENT_BINARY_DIR}/../../unit/graph/hipMatMul.code -I${CMAKE_CURRENT_SOURCE_DIR}/../../../../include/ -I${CMAKE_CURRENT_SOURCE_DIR}/../../include --rocm-path=${ROCM_PATH})
|
||||
add_dependencies(build_tests hipMatMul)
|
||||
endif()
|
||||
|
||||
add_dependencies(build_tests add_Kernel.code)
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNNESS 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 INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include "hip/hip_runtime.h"
|
||||
extern "C" __global__ void Add(int* a, int* b, int* c) {
|
||||
size_t tx = (blockIdx.x * blockDim.x + threadIdx.x);
|
||||
c[tx] = a[tx] + b[tx];
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved.
|
||||
Copyright (c) 2023 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
|
||||
@@ -18,12 +18,47 @@ 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 <hip_test_common.hh>
|
||||
#include <hip_test_kernels.hh>
|
||||
#include <hip_test_checkers.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
|
||||
/* Test verifies hipGraphAddKernelNode API Negative scenarios.
|
||||
#define CODEOBJ_FILE "add_Kernel.code"
|
||||
#define KERNEL_NAME "Add"
|
||||
#define THREADS_PER_BLOCK 512
|
||||
|
||||
/**
|
||||
* @addtogroup hipGraphAddKernelNode hipModuleLoad hipModuleGetFunction
|
||||
* @{
|
||||
* @ingroup GraphTest
|
||||
* `hipError_t hipGraphAddKernelNode(hipGraphNode_t* pGraphNode, hipGraph_t graph,
|
||||
const hipGraphNode_t* pDependencies, size_t numDependencies,
|
||||
const hipKernelNodeParams* pNodeParams)` -
|
||||
* Creates a kernel execution node and adds it to a graph
|
||||
* `hipError_t hipModuleLoad(hipModule_t* module, const char* fname)` -
|
||||
* Loads code object from file into a module the currrent context
|
||||
* `hipError_t hipModuleGetFunction(hipFunction_t* function, hipModule_t module, const char* kname)` -
|
||||
* Function with kname will be extracted if present in module
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test case to verify negative scenarios of hipGraphAddKernelNode API.
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/graph/hipGraphAddKernelNode.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.6
|
||||
*/
|
||||
|
||||
constexpr size_t size = 1 << 12;
|
||||
enum fnType {
|
||||
normal,
|
||||
object
|
||||
};
|
||||
|
||||
TEST_CASE("Unit_hipGraphAddKernelNode_Negative") {
|
||||
constexpr int N = 1024;
|
||||
size_t NElem{N};
|
||||
@@ -48,46 +83,46 @@ TEST_CASE("Unit_hipGraphAddKernelNode_Negative") {
|
||||
kNodeParams.kernelParams = reinterpret_cast<void**>(kernelArgs);
|
||||
|
||||
SECTION("Pass pGraphNode as nullptr") {
|
||||
HIP_CHECK_ERROR(hipGraphAddKernelNode(nullptr, graph, nullptr, 0, &kNodeParams),
|
||||
hipErrorInvalidValue);
|
||||
HIP_CHECK_ERROR(hipGraphAddKernelNode(nullptr, graph, nullptr,
|
||||
0, &kNodeParams), hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
SECTION("Pass Graph as nullptr") {
|
||||
HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, nullptr, nullptr, 0, &kNodeParams),
|
||||
hipErrorInvalidValue);
|
||||
HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, nullptr, nullptr,
|
||||
0, &kNodeParams), hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
SECTION("Pass invalid numDependencies") {
|
||||
HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, graph, nullptr, 11, &kNodeParams),
|
||||
hipErrorInvalidValue);
|
||||
HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, graph, nullptr, 11,
|
||||
&kNodeParams), hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
SECTION("Pass invalid numDependencies and valid list for dependencies") {
|
||||
HIP_CHECK(hipGraphAddKernelNode(&kNode, graph, nullptr, 0, &kNodeParams));
|
||||
dependencies.push_back(kNode);
|
||||
HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, graph, dependencies.data(),
|
||||
dependencies.size() + 1, &kNodeParams),
|
||||
hipErrorInvalidValue);
|
||||
dependencies.size() + 1,
|
||||
&kNodeParams), hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
SECTION("Pass NodeParams as nullptr") {
|
||||
HIP_CHECK_ERROR(
|
||||
hipGraphAddKernelNode(&kNode, graph, dependencies.data(), dependencies.size(), nullptr),
|
||||
hipErrorInvalidValue);
|
||||
hipGraphAddKernelNode(&kNode, graph, dependencies.data(),
|
||||
dependencies.size(), nullptr), hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
#if HT_NVIDIA // on AMD this returns hipErrorInvalidValue
|
||||
SECTION("Pass NodeParams func data member as nullptr") {
|
||||
kNodeParams.func = nullptr;
|
||||
HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, graph, nullptr, 0, &kNodeParams),
|
||||
hipErrorInvalidDeviceFunction);
|
||||
HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, graph, nullptr, 0,
|
||||
&kNodeParams), hipErrorInvalidDeviceFunction);
|
||||
}
|
||||
#endif
|
||||
|
||||
SECTION("Pass kernelParams data member as nullptr") {
|
||||
kNodeParams.kernelParams = nullptr;
|
||||
HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, graph, nullptr, 0, &kNodeParams),
|
||||
hipErrorInvalidValue);
|
||||
HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, graph, nullptr, 0,
|
||||
&kNodeParams), hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
#if HT_AMD // On Cuda setup this test case getting failed
|
||||
@@ -95,8 +130,8 @@ TEST_CASE("Unit_hipGraphAddKernelNode_Negative") {
|
||||
hipGraph_t destroyed_graph;
|
||||
HIP_CHECK(hipGraphCreate(&destroyed_graph, 0));
|
||||
HIP_CHECK(hipGraphDestroy(destroyed_graph));
|
||||
HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, destroyed_graph, nullptr, 0, &kNodeParams),
|
||||
hipErrorInvalidValue);
|
||||
HIP_CHECK_ERROR(hipGraphAddKernelNode(&kNode, destroyed_graph, nullptr,
|
||||
0, &kNodeParams), hipErrorInvalidValue);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -105,3 +140,327 @@ TEST_CASE("Unit_hipGraphAddKernelNode_Negative") {
|
||||
HIP_CHECK(hipFree(C_d));
|
||||
HIP_CHECK(hipGraphDestroy(graph));
|
||||
}
|
||||
#if HT_AMD
|
||||
static __global__ void Add(int* A_d, int* B_d, int* C_d) {
|
||||
size_t tx = (blockIdx.x * blockDim.x + threadIdx.x);
|
||||
C_d[tx] = A_d[tx] + B_d[tx];
|
||||
}
|
||||
static void validateOutput(const hipGraph_t &graph , int* A_h,
|
||||
int* B_h, int* C_h,
|
||||
size_t inputSize) {
|
||||
hipStream_t streamForGraph;
|
||||
HIP_CHECK(hipStreamCreate(&streamForGraph));
|
||||
hipGraphExec_t graphExec;
|
||||
HIP_CHECK(hipGraphInstantiate(&graphExec, graph, nullptr, nullptr, 0));
|
||||
HIP_CHECK(hipGraphLaunch(graphExec, streamForGraph));
|
||||
HIP_CHECK(hipStreamSynchronize(streamForGraph));
|
||||
|
||||
HIP_CHECK(hipGraphExecDestroy(graphExec));
|
||||
HIP_CHECK(hipStreamDestroy(streamForGraph));
|
||||
// Verify output
|
||||
for (size_t i = 0; i < inputSize; i++) {
|
||||
REQUIRE((A_h[i] + B_h[i]) == C_h[i]);
|
||||
}
|
||||
}
|
||||
static void kernelFnChange(int* A_d, int* A_h,
|
||||
int* B_d, int* B_h, int* C_d, int* C_h,
|
||||
size_t inputSize, size_t numOfBlocks, enum fnType fn) {
|
||||
hipGraph_t graph;
|
||||
std::vector<hipGraphNode_t> nodeDependencies;
|
||||
hipGraphNode_t memcpyNode, memcpyNode1, memcpyNode2, kernelNode;
|
||||
|
||||
hipModule_t Module;
|
||||
hipFunction_t Function;
|
||||
HIPCHECK(hipModuleLoad(&Module, CODEOBJ_FILE));
|
||||
HIPCHECK(hipModuleGetFunction(&Function, Module, KERNEL_NAME));
|
||||
|
||||
HIP_CHECK(hipGraphCreate(&graph, 0));
|
||||
// Add MemCpy nodes H2D
|
||||
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyNode, graph, nullptr, 0, A_d,
|
||||
A_h, sizeof(int)*inputSize, hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyNode1, graph, nullptr, 0, B_d,
|
||||
B_h, sizeof(int)*inputSize, hipMemcpyHostToDevice));
|
||||
nodeDependencies.push_back(memcpyNode);
|
||||
nodeDependencies.push_back(memcpyNode1);
|
||||
// kernel node.
|
||||
hipKernelNodeParams kernelNodeParams{}, kernelNodeParamsUpdate{};
|
||||
void* kernelArgs[4] = {reinterpret_cast<void*>(&A_d),
|
||||
reinterpret_cast<void*>(&B_d),
|
||||
reinterpret_cast<void*>(&C_d),
|
||||
&numOfBlocks};
|
||||
if (fn == normal) { // normal function
|
||||
kernelNodeParams.func = reinterpret_cast<void*>(Add);
|
||||
} else { // Code Object function
|
||||
kernelNodeParams.func = reinterpret_cast<void*>(Function);
|
||||
}
|
||||
kernelNodeParams.gridDim = dim3(inputSize / THREADS_PER_BLOCK, 1, 1);
|
||||
kernelNodeParams.blockDim = dim3(THREADS_PER_BLOCK, 1, 1);
|
||||
kernelNodeParams.sharedMemBytes = 0;
|
||||
kernelNodeParams.kernelParams = reinterpret_cast<void**>(kernelArgs);
|
||||
kernelNodeParams.extra = nullptr;
|
||||
HIP_CHECK(hipGraphAddKernelNode(&kernelNode, graph, nodeDependencies.data(),
|
||||
nodeDependencies.size(), &kernelNodeParams));
|
||||
if (fn == normal) {
|
||||
kernelNodeParamsUpdate.func = reinterpret_cast<void*>(Function);
|
||||
} else {
|
||||
kernelNodeParamsUpdate.func = reinterpret_cast<void*>(Add);
|
||||
}
|
||||
kernelNodeParamsUpdate.gridDim = dim3(inputSize / THREADS_PER_BLOCK, 1, 1);
|
||||
kernelNodeParamsUpdate.blockDim = dim3(THREADS_PER_BLOCK, 1, 1);
|
||||
kernelNodeParamsUpdate.sharedMemBytes = 0;
|
||||
kernelNodeParamsUpdate.kernelParams = reinterpret_cast<void**>(kernelArgs);
|
||||
kernelNodeParamsUpdate.extra = nullptr;
|
||||
HIP_CHECK(hipGraphKernelNodeSetParams(kernelNode, &kernelNodeParamsUpdate));
|
||||
nodeDependencies.clear();
|
||||
nodeDependencies.push_back(kernelNode);
|
||||
|
||||
// Add MemCpy nodes D2H
|
||||
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyNode2, graph,
|
||||
nodeDependencies.data(), nodeDependencies.size(), C_h,
|
||||
C_d, sizeof(int)*inputSize, hipMemcpyDeviceToHost));
|
||||
nodeDependencies.clear();
|
||||
|
||||
// Validation
|
||||
validateOutput(graph, A_h, B_h, C_h, inputSize);
|
||||
|
||||
HIP_CHECK(hipGraphDestroy(graph));
|
||||
HIPCHECK(hipModuleUnload(Module));
|
||||
}
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test case to verify kernel function output in the graph, cloned graph by adding
|
||||
* hipGraphAddKernelNode by loading kernerl function through hipModuleLoad,
|
||||
* hipModuleGetFunction from the code object file.
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/graph/hipGraphAddKernelNode.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.6
|
||||
*/
|
||||
TEST_CASE("Unit_hipGraphAddKernelNode_moduleLoadKernelFn_graphNclonedGraph") {
|
||||
int *A_d, *B_d, *C_d;
|
||||
int *A_h, *B_h, *C_h;
|
||||
HipTest::initArrays<int>(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, size, false);
|
||||
|
||||
hipGraph_t graph, clonedGraph;
|
||||
std::vector<hipGraphNode_t> nodeDependencies;
|
||||
hipGraphNode_t memcpyNode, memcpyNode1, memcpyNode2, kernelNode;
|
||||
HIP_CHECK(hipGraphCreate(&graph, 0));
|
||||
|
||||
hipModule_t Module;
|
||||
hipFunction_t Function;
|
||||
HIPCHECK(hipModuleLoad(&Module, CODEOBJ_FILE));
|
||||
HIPCHECK(hipModuleGetFunction(&Function, Module, KERNEL_NAME));
|
||||
|
||||
// Add MemCpy nodes H2D
|
||||
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyNode, graph, nullptr, 0, A_d,
|
||||
A_h, sizeof(int)*size, hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyNode1, graph, nullptr, 0, B_d,
|
||||
B_h, sizeof(int)*size, hipMemcpyHostToDevice));
|
||||
nodeDependencies.push_back(memcpyNode);
|
||||
nodeDependencies.push_back(memcpyNode1);
|
||||
|
||||
// Add Kernel Node
|
||||
hipKernelNodeParams kernelNodeParams{};
|
||||
void* kernelArgs[3] = {reinterpret_cast<void*>(&A_d),
|
||||
reinterpret_cast<void*>(&B_d),
|
||||
reinterpret_cast<void*>(&C_d)};
|
||||
kernelNodeParams.func = reinterpret_cast<void*>(Function);
|
||||
kernelNodeParams.gridDim = dim3(size / THREADS_PER_BLOCK, 1, 1);
|
||||
kernelNodeParams.blockDim = dim3(THREADS_PER_BLOCK, 1, 1);
|
||||
kernelNodeParams.sharedMemBytes = 0;
|
||||
kernelNodeParams.kernelParams = reinterpret_cast<void**>(kernelArgs);
|
||||
kernelNodeParams.extra = nullptr;
|
||||
HIP_CHECK(hipGraphAddKernelNode(&kernelNode, graph, nodeDependencies.data(),
|
||||
nodeDependencies.size(), &kernelNodeParams));
|
||||
nodeDependencies.clear();
|
||||
nodeDependencies.push_back(kernelNode);
|
||||
|
||||
// Add MemCpy nodes D2H
|
||||
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyNode2, graph,
|
||||
nodeDependencies.data(), nodeDependencies.size(), C_h,
|
||||
C_d, sizeof(int)*size, hipMemcpyDeviceToHost));
|
||||
nodeDependencies.clear();
|
||||
SECTION("Original Graph") {
|
||||
// Original Graph validation
|
||||
validateOutput(graph, A_h, B_h, C_h, size);
|
||||
}
|
||||
SECTION("Cloned Graph") {
|
||||
// Clone the graph
|
||||
HIP_CHECK(hipGraphClone(&clonedGraph, graph));
|
||||
// Cloned graph Validation
|
||||
validateOutput(clonedGraph, A_h, B_h, C_h, size);
|
||||
HIP_CHECK(hipGraphDestroy(clonedGraph));
|
||||
}
|
||||
HIP_CHECK(hipGraphDestroy(graph));
|
||||
HIPCHECK(hipModuleUnload(Module));
|
||||
HipTest::freeArrays<int>(A_d, B_d, C_d, A_h, B_h, C_h, false);
|
||||
}
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test case to verify kernel function output by adding hipGraphAddKernelNode and updating the
|
||||
* kernel functions from normal to Code object and vice versa in the graph by loading kernerl
|
||||
* function through hipModuleLoad, hipModuleGetFunction from code object file.
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/graph/hipGraphAddKernelNode.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.6
|
||||
*/
|
||||
TEST_CASE("Unit_hipGraphAddKernelNode_moduleLoadKernelFn_kernelFnUpdate") {
|
||||
size_t maxBlocks = 512;
|
||||
int *A_d, *B_d, *C_d; // Device pointers
|
||||
int *A_h, *B_h, *C_h; // Host Pointers
|
||||
HipTest::initArrays<int>(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, size, false);
|
||||
|
||||
SECTION("Kernel function change from Normal fn to Code object fn") {
|
||||
kernelFnChange(A_d, A_h, B_d, B_h, C_d, C_h, size, maxBlocks, object);
|
||||
}
|
||||
SECTION("Kernel function change from Code object fn to normal fn") {
|
||||
kernelFnChange(A_d, A_h, B_d, B_h, C_d, C_h, size, maxBlocks, normal);
|
||||
}
|
||||
|
||||
HipTest::freeArrays<int>(A_d, B_d, C_d, A_h, B_h, C_h, false);
|
||||
}
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test case to verify kernel function output in the child graph and cloned graph by adding
|
||||
* hipGraphAddKernelNode by loading kernerl function through hipModuleLoad,
|
||||
* hipModuleGetFunction from the code object file.
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/graph/hipGraphAddKernelNode.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.6
|
||||
*/
|
||||
TEST_CASE("Unit_hipGraphAddKernelNode_moduleLoadKernelFn_childGraph") {
|
||||
int *A_d, *B_d, *C_d; // Device pointers
|
||||
int *A_h, *B_h, *C_h; // Host Pointers
|
||||
HipTest::initArrays<int>(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, size, false);
|
||||
|
||||
hipGraph_t graph, childgraph, clonedGraph;
|
||||
std::vector<hipGraphNode_t> nodeDependencies;
|
||||
hipGraphNode_t memcpyh2d1, memcpyh2d2, memcpyd2h, childGraphNode, kernelNode;
|
||||
|
||||
hipModule_t Module;
|
||||
hipFunction_t Function;
|
||||
HIPCHECK(hipModuleLoad(&Module, CODEOBJ_FILE));
|
||||
HIPCHECK(hipModuleGetFunction(&Function, Module, KERNEL_NAME));
|
||||
|
||||
// Create child graph
|
||||
HIP_CHECK(hipGraphCreate(&childgraph, 0));
|
||||
|
||||
// kerrel params.
|
||||
hipKernelNodeParams kernelNodeParams{};
|
||||
void* kernelArgs[3] = {reinterpret_cast<void*>(&A_d),
|
||||
reinterpret_cast<void*>(&B_d),
|
||||
reinterpret_cast<void*>(&C_d)};
|
||||
kernelNodeParams.func = reinterpret_cast<void*>(Function);
|
||||
kernelNodeParams.gridDim = dim3(size / THREADS_PER_BLOCK, 1, 1);
|
||||
kernelNodeParams.blockDim = dim3(THREADS_PER_BLOCK, 1, 1);
|
||||
kernelNodeParams.sharedMemBytes = 0;
|
||||
kernelNodeParams.kernelParams = reinterpret_cast<void**>(kernelArgs);
|
||||
kernelNodeParams.extra = nullptr;
|
||||
HIP_CHECK(hipGraphAddKernelNode(&kernelNode, childgraph, nullptr,
|
||||
0, &kernelNodeParams));
|
||||
|
||||
HIP_CHECK(hipGraphCreate(&graph, 0));
|
||||
// Add MemCpy nodes H2D
|
||||
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyh2d1, graph, nullptr, 0, A_d,
|
||||
A_h, sizeof(int)*size, hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyh2d2, graph, nullptr, 0, B_d,
|
||||
B_h, sizeof(int)*size, hipMemcpyHostToDevice));
|
||||
nodeDependencies.push_back(memcpyh2d1);
|
||||
nodeDependencies.push_back(memcpyh2d2);
|
||||
// Add child graph node
|
||||
HIP_CHECK(hipGraphAddChildGraphNode(&childGraphNode, graph,
|
||||
nullptr,
|
||||
0, childgraph));
|
||||
nodeDependencies.push_back(childGraphNode);
|
||||
|
||||
// Add MemCpy nodes D2H
|
||||
HIP_CHECK(hipGraphAddMemcpyNode1D(&memcpyd2h, graph,
|
||||
nodeDependencies.data(), nodeDependencies.size(), C_h,
|
||||
C_d, sizeof(int)*size, hipMemcpyDeviceToHost));
|
||||
nodeDependencies.clear();
|
||||
|
||||
SECTION("Original Graph") {
|
||||
// Original Graph validation
|
||||
validateOutput(graph, A_h, B_h, C_h, size);
|
||||
}
|
||||
SECTION("Cloned Graph") {
|
||||
// Clone the graph
|
||||
HIP_CHECK(hipGraphClone(&clonedGraph, graph));
|
||||
// Cloned Graph validation
|
||||
validateOutput(clonedGraph, A_h, B_h, C_h, size);
|
||||
HIP_CHECK(hipGraphDestroy(clonedGraph));
|
||||
}
|
||||
HIP_CHECK(hipGraphDestroy(graph));
|
||||
HIPCHECK(hipModuleUnload(Module));
|
||||
HipTest::freeArrays<int>(A_d, B_d, C_d, A_h, B_h, C_h, false);
|
||||
}
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test case to verify kernel function output in the graph which is created by stream capture.
|
||||
* The kernel function is loading through hipModuleLoad, hipModuleGetFunction from code object file
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/graph/hipGraphAddKernelNode.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.6
|
||||
*/
|
||||
TEST_CASE("Unit_hipGraphAddKernelNode_moduleLoadKernelFn_streamCapture") {
|
||||
size_t maxBlocks = 512;
|
||||
size_t Nbytes = sizeof(int)*maxBlocks;
|
||||
|
||||
int *A_d, *B_d, *C_d; // Device pointers
|
||||
int *A_h, *B_h, *C_h; // Host Pointers
|
||||
HipTest::initArrays<int>(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, maxBlocks,
|
||||
false);
|
||||
|
||||
hipGraph_t graph;
|
||||
hipStream_t stream;
|
||||
|
||||
hipModule_t Module;
|
||||
hipFunction_t Function;
|
||||
HIPCHECK(hipModuleLoad(&Module, CODEOBJ_FILE));
|
||||
HIPCHECK(hipModuleGetFunction(&Function, Module, KERNEL_NAME));
|
||||
|
||||
HIP_CHECK(hipStreamCreate(&stream));
|
||||
HIP_CHECK(hipStreamBeginCapture(stream, hipStreamCaptureModeGlobal));
|
||||
|
||||
// MemCpy node H2D
|
||||
HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice,
|
||||
stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_d, B_h, Nbytes, hipMemcpyHostToDevice,
|
||||
stream));
|
||||
// kerrel params.
|
||||
void* kernelArgs[] = {&A_d, &B_d, &C_d};
|
||||
|
||||
// Kernel node
|
||||
HIP_CHECK(hipModuleLaunchKernel(Function, 1, 1, 1, maxBlocks, 1, 1, 0,
|
||||
stream, kernelArgs, nullptr));
|
||||
|
||||
// MemCpy nodes D2H
|
||||
HIP_CHECK(hipMemcpyAsync(C_h, C_d, Nbytes, hipMemcpyDeviceToHost,
|
||||
stream));
|
||||
HIP_CHECK(hipStreamEndCapture(stream, &graph));
|
||||
HIP_CHECK(hipStreamDestroy(stream));
|
||||
|
||||
// validation
|
||||
validateOutput(graph, A_h, B_h, C_h, maxBlocks);
|
||||
|
||||
HIP_CHECK(hipGraphDestroy(graph));
|
||||
HIPCHECK(hipModuleUnload(Module));
|
||||
HipTest::freeArrays<int>(A_d, B_d, C_d, A_h, B_h, C_h, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -23,7 +23,25 @@ set(TEST_SRC
|
||||
hipMemFaultStackAllocation.cc
|
||||
hipLaunchBounds.cc
|
||||
hipShflTests.cc
|
||||
hipTestConstant.cc
|
||||
hipTestGlobalVariable.cc
|
||||
hipTestMemKernel.cc
|
||||
launch_bounds.cc
|
||||
inline_asm_vadd.cc
|
||||
)
|
||||
if(UNIX)
|
||||
set(TEST_SRC ${TEST_SRC}
|
||||
hipPrintfKernel.cc)
|
||||
endif()
|
||||
string(FIND "${OFFLOAD_ARCH_STR}" "gfx1030" RESULT)
|
||||
if ("${RESULT}" EQUAL "-1")
|
||||
set(AMD_TEST_SRC
|
||||
inline_asm_vmac.cc)
|
||||
endif()
|
||||
|
||||
if(HIP_PLATFORM MATCHES "amd")
|
||||
set(TEST_SRC ${TEST_SRC} ${AMD_TEST_SRC})
|
||||
endif()
|
||||
|
||||
# only for AMD
|
||||
if(HIP_PLATFORM MATCHES "amd")
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNNESS 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 INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
#include <cstring>
|
||||
#include "../kernel/printf_common.h"
|
||||
|
||||
#define HIP_ENABLE_PRINTF
|
||||
|
||||
__global__ void run_printf() {
|
||||
printf("Hello World\n");
|
||||
}
|
||||
/**
|
||||
* @addtogroup hipLaunchKernelGGL
|
||||
* @{
|
||||
* @ingroup KernelTest
|
||||
* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
|
||||
std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` -
|
||||
* Method to invocate kernel functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test case to check printf function via kernel call.
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/kernel/hipPrintfKernel.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.6
|
||||
*/
|
||||
TEST_CASE("Unit_kernel_ChkPrintf") {
|
||||
int device_count = 0;
|
||||
CaptureStream capture(stdout);
|
||||
HIP_CHECK(hipGetDeviceCount(&device_count));
|
||||
std::string st = "Hello World";
|
||||
const char * check = st.c_str();
|
||||
for (int i = 0; i < device_count; ++i) {
|
||||
HIP_CHECK(hipSetDevice(i));
|
||||
hipLaunchKernelGGL(run_printf, dim3(1), dim3(1), 0, 0);
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
char* data = new char[st.size()];;
|
||||
std::ifstream CapturedData = capture.getCapturedData();
|
||||
CapturedData.getline(data, st.size()+1);
|
||||
int result = strcmp(data, check);
|
||||
REQUIRE(result == 0);
|
||||
delete [] data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNNESS 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 INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
|
||||
#define LEN 512
|
||||
#define SIZE 2048
|
||||
|
||||
__constant__ int Value[LEN];
|
||||
|
||||
static __global__ void Get(int* Ad) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
Ad[tid] = Value[tid];
|
||||
}
|
||||
/**
|
||||
* @addtogroup hipLaunchKernelGGL
|
||||
* @{
|
||||
* @ingroup KernelTest
|
||||
* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
|
||||
std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` -
|
||||
* Method to invocate kernel functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test case to check const variable via kernel call.
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/kernel/hipTestConstant.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.6
|
||||
*/
|
||||
|
||||
TEST_CASE("Unit_kernel_chkConstantViaKernel") {
|
||||
int *A, *B, *Ad;
|
||||
A = new int[LEN];
|
||||
B = new int[LEN];
|
||||
for (unsigned i = 0; i < LEN; i++) {
|
||||
A[i] = -1 * i;
|
||||
B[i] = 0;
|
||||
}
|
||||
|
||||
HIP_CHECK(hipMalloc(reinterpret_cast<void**>(&Ad), SIZE));
|
||||
|
||||
HIP_CHECK(hipMemcpyToSymbol(HIP_SYMBOL(Value), A, SIZE, 0,
|
||||
hipMemcpyHostToDevice));
|
||||
hipLaunchKernelGGL(Get, dim3(1, 1, 1), dim3(LEN, 1, 1), 0, 0, Ad);
|
||||
HIP_CHECK(hipMemcpy(B, Ad, SIZE, hipMemcpyDeviceToHost));
|
||||
|
||||
for (unsigned i = 0; i < LEN; i++) {
|
||||
REQUIRE(A[i] == B[i]);
|
||||
}
|
||||
delete [] A;
|
||||
delete [] B;
|
||||
HIP_CHECK(hipFree(Ad));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNNESS 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 INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
|
||||
#define LEN 512
|
||||
#define SIZE 2048
|
||||
/**
|
||||
* @addtogroup hipLaunchKernelGGL
|
||||
* @{
|
||||
* @ingroup KernelTest
|
||||
* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
|
||||
std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` -
|
||||
* Method to invocate kernel functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test case to check constant global variable and global array via kernel call.
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/kernel/hipTestGlobalVariable.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.6
|
||||
*/
|
||||
__constant__ int ConstantGlobalVar = 123;
|
||||
|
||||
static __global__ void kernel(int* Ad) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
Ad[tid] = ConstantGlobalVar;
|
||||
}
|
||||
|
||||
void runTestConstantGlobalVar() {
|
||||
int *A, *Ad;
|
||||
A = new int[LEN];
|
||||
for (unsigned i = 0; i < LEN; i++) {
|
||||
A[i] = 0;
|
||||
}
|
||||
HIP_CHECK(hipMalloc(reinterpret_cast<void**>(&Ad), SIZE));
|
||||
hipLaunchKernelGGL(kernel, dim3(1, 1, 1), dim3(LEN, 1, 1), 0, 0, Ad);
|
||||
HIP_CHECK(hipMemcpy(A, Ad, SIZE, hipMemcpyDeviceToHost));
|
||||
|
||||
for (unsigned i = 0; i < LEN; i++) {
|
||||
REQUIRE(123 == A[i]);
|
||||
}
|
||||
delete [] A;
|
||||
HIP_CHECK(hipFree(Ad));
|
||||
}
|
||||
|
||||
__device__ int GlobalArray[LEN];
|
||||
static __global__ void kernelWrite() {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
GlobalArray[tid] = tid;
|
||||
}
|
||||
static __global__ void kernelRead(int* Ad) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
Ad[tid] = GlobalArray[tid];
|
||||
}
|
||||
|
||||
void runTestGlobalArray() {
|
||||
int *A, *Ad;
|
||||
A = new int[LEN];
|
||||
for (unsigned i = 0; i < LEN; i++) {
|
||||
A[i] = 0;
|
||||
}
|
||||
|
||||
HIP_CHECK(hipMalloc(reinterpret_cast<void**>(&Ad), SIZE));
|
||||
hipLaunchKernelGGL(kernelWrite, dim3(1, 1, 1), dim3(LEN, 1, 1), 0, 0);
|
||||
hipLaunchKernelGGL(kernelRead, dim3(1, 1, 1), dim3(LEN, 1, 1), 0, 0, Ad);
|
||||
HIP_CHECK(hipMemcpy(A, Ad, SIZE, hipMemcpyDeviceToHost));
|
||||
|
||||
for (unsigned i = 0; i < LEN; i++) {
|
||||
REQUIRE(i == A[i]);
|
||||
}
|
||||
delete [] A;
|
||||
HIP_CHECK(hipFree(Ad));
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_kernel_chkGlobalArrAndGlobalVaribleViaKernelFn") {
|
||||
runTestConstantGlobalVar();
|
||||
runTestGlobalArray();
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNNESS 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 INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
|
||||
#define LEN8 8 * 4
|
||||
#define LEN9 9 * 4
|
||||
#define LEN10 10 * 4
|
||||
#define LEN11 11 * 4
|
||||
#define LEN12 12 * 4
|
||||
|
||||
__global__ void MemCpy8(uint8_t* In, uint8_t* Out) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
memcpy(Out + tid * 8, In + tid * 8, 8);
|
||||
}
|
||||
|
||||
__global__ void MemCpy9(uint8_t* In, uint8_t* Out) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
memcpy(Out + tid * 9, In + tid * 9, 9);
|
||||
}
|
||||
|
||||
__global__ void MemCpy10(uint8_t* In, uint8_t* Out) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
memcpy(Out + tid * 10, In + tid * 10, 10);
|
||||
}
|
||||
|
||||
__global__ void MemCpy11(uint8_t* In, uint8_t* Out) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
memcpy(Out + tid * 11, In + tid * 11, 11);
|
||||
}
|
||||
|
||||
__global__ void MemCpy12(uint8_t* In, uint8_t* Out) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
memcpy(Out + tid * 12, In + tid * 12, 12);
|
||||
}
|
||||
|
||||
__global__ void MemSet8(uint8_t* In) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
memset(In + tid * 8, 1, 8);
|
||||
}
|
||||
|
||||
__global__ void MemSet9(uint8_t* In) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
memset(In + tid * 9, 1, 9);
|
||||
}
|
||||
|
||||
__global__ void MemSet10(uint8_t* In) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
memset(In + tid * 10, 1, 10);
|
||||
}
|
||||
|
||||
__global__ void MemSet11(uint8_t* In) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
memset(In + tid * 11, 1, 11);
|
||||
}
|
||||
|
||||
__global__ void MemSet12(uint8_t* In) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
memset(In + tid * 12, 1, 12);
|
||||
}
|
||||
/**
|
||||
* @addtogroup hipLaunchKernelGGL
|
||||
* @{
|
||||
* @ingroup KernelTest
|
||||
* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
|
||||
std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` -
|
||||
* Method to invocate kernel functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test case to check memcpy and memset via kernel call.
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/kernel/hipTestMemKernel.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.6
|
||||
*/
|
||||
|
||||
TEST_CASE("Unit_kernel_MemoryOperationsViaKernels") {
|
||||
uint8_t *A, *Ad, *B, *Bd, *C, *Cd;
|
||||
A = new uint8_t[LEN8];
|
||||
B = new uint8_t[LEN8];
|
||||
C = new uint8_t[LEN8];
|
||||
for (uint32_t i = 0; i < LEN8; i++) {
|
||||
A[i] = i;
|
||||
B[i] = 0;
|
||||
C[i] = 0;
|
||||
}
|
||||
HIP_CHECK(hipMalloc(&Ad, LEN8));
|
||||
HIP_CHECK(hipMalloc(&Bd, LEN8));
|
||||
HIP_CHECK(hipMalloc(&Cd, LEN8));
|
||||
HIP_CHECK(hipMemcpy(Ad, A, LEN8, hipMemcpyHostToDevice));
|
||||
hipLaunchKernelGGL(MemCpy8, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Ad, Bd);
|
||||
hipLaunchKernelGGL(MemSet8, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Cd);
|
||||
HIP_CHECK(hipMemcpy(B, Bd, LEN8, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipMemcpy(C, Cd, LEN8, hipMemcpyDeviceToHost));
|
||||
for (uint32_t i = 0; i < LEN8; i++) {
|
||||
REQUIRE(A[i] == B[i]);
|
||||
REQUIRE(C[i] == 1);
|
||||
}
|
||||
|
||||
delete[] A;
|
||||
delete[] B;
|
||||
delete[] C;
|
||||
HIP_CHECK(hipFree(Ad));
|
||||
HIP_CHECK(hipFree(Bd));
|
||||
HIP_CHECK(hipFree(Cd));
|
||||
|
||||
SECTION("MemCpySet1") {
|
||||
A = new uint8_t[LEN9];
|
||||
B = new uint8_t[LEN9];
|
||||
C = new uint8_t[LEN9];
|
||||
for (uint32_t i = 0; i < LEN9; i++) {
|
||||
A[i] = i;
|
||||
B[i] = 0;
|
||||
C[i] = 0;
|
||||
}
|
||||
HIP_CHECK(hipMalloc(&Ad, LEN9));
|
||||
HIP_CHECK(hipMalloc(&Bd, LEN9));
|
||||
HIP_CHECK(hipMalloc(&Cd, LEN9));
|
||||
HIP_CHECK(hipMemcpy(Ad, A, LEN9, hipMemcpyHostToDevice));
|
||||
hipLaunchKernelGGL(MemCpy9, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Ad, Bd);
|
||||
hipLaunchKernelGGL(MemSet9, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Cd);
|
||||
HIP_CHECK(hipMemcpy(B, Bd, LEN9, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipMemcpy(C, Cd, LEN9, hipMemcpyDeviceToHost));
|
||||
for (uint32_t i = 0; i < LEN9; i++) {
|
||||
REQUIRE(A[i] == B[i]);
|
||||
REQUIRE(C[i] == 1);
|
||||
}
|
||||
|
||||
delete[] A;
|
||||
delete[] B;
|
||||
delete[] C;
|
||||
HIP_CHECK(hipFree(Ad));
|
||||
HIP_CHECK(hipFree(Bd));
|
||||
HIP_CHECK(hipFree(Cd));
|
||||
}
|
||||
|
||||
SECTION("MemCpySet2") {
|
||||
A = new uint8_t[LEN10];
|
||||
B = new uint8_t[LEN10];
|
||||
C = new uint8_t[LEN10];
|
||||
for (uint32_t i = 0; i < LEN10; i++) {
|
||||
A[i] = i;
|
||||
B[i] = 0;
|
||||
C[i] = 0;
|
||||
}
|
||||
HIP_CHECK(hipMalloc(&Ad, LEN10));
|
||||
HIP_CHECK(hipMalloc(&Bd, LEN10));
|
||||
HIP_CHECK(hipMalloc(&Cd, LEN10));
|
||||
HIP_CHECK(hipMemcpy(Ad, A, LEN10, hipMemcpyHostToDevice));
|
||||
hipLaunchKernelGGL(MemCpy10, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Ad, Bd);
|
||||
hipLaunchKernelGGL(MemSet10, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Cd);
|
||||
HIP_CHECK(hipMemcpy(B, Bd, LEN10, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipMemcpy(C, Cd, LEN10, hipMemcpyDeviceToHost));
|
||||
for (uint32_t i = 0; i < LEN10; i++) {
|
||||
REQUIRE(A[i] == B[i]);
|
||||
REQUIRE(C[i] == 1);
|
||||
}
|
||||
|
||||
delete[] A;
|
||||
delete[] B;
|
||||
delete[] C;
|
||||
HIP_CHECK(hipFree(Ad));
|
||||
HIP_CHECK(hipFree(Bd));
|
||||
HIP_CHECK(hipFree(Cd));
|
||||
}
|
||||
|
||||
SECTION("MemCpySet3") {
|
||||
A = new uint8_t[LEN11];
|
||||
B = new uint8_t[LEN11];
|
||||
C = new uint8_t[LEN11];
|
||||
for (uint32_t i = 0; i < LEN11; i++) {
|
||||
A[i] = i;
|
||||
B[i] = 0;
|
||||
C[i] = 0;
|
||||
}
|
||||
HIP_CHECK(hipMalloc(&Ad, LEN11));
|
||||
HIP_CHECK(hipMalloc(&Bd, LEN11));
|
||||
HIP_CHECK(hipMalloc(&Cd, LEN11));
|
||||
HIP_CHECK(hipMemcpy(Ad, A, LEN11, hipMemcpyHostToDevice));
|
||||
hipLaunchKernelGGL(MemCpy11, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Ad, Bd);
|
||||
hipLaunchKernelGGL(MemSet11, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Cd);
|
||||
HIP_CHECK(hipMemcpy(B, Bd, LEN11, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipMemcpy(C, Cd, LEN11, hipMemcpyDeviceToHost));
|
||||
for (uint32_t i = 0; i < LEN11; i++) {
|
||||
REQUIRE(A[i] == B[i]);
|
||||
REQUIRE(C[i] == 1);
|
||||
}
|
||||
|
||||
delete[] A;
|
||||
delete[] B;
|
||||
delete[] C;
|
||||
HIP_CHECK(hipFree(Ad));
|
||||
HIP_CHECK(hipFree(Bd));
|
||||
HIP_CHECK(hipFree(Cd));
|
||||
}
|
||||
|
||||
SECTION("MemCpySet4") {
|
||||
A = new uint8_t[LEN12];
|
||||
B = new uint8_t[LEN12];
|
||||
C = new uint8_t[LEN12];
|
||||
for (uint32_t i = 0; i < LEN12; i++) {
|
||||
A[i] = i;
|
||||
B[i] = 0;
|
||||
C[i] = 0;
|
||||
}
|
||||
HIP_CHECK(hipMalloc(&Ad, LEN12));
|
||||
HIP_CHECK(hipMalloc(&Bd, LEN12));
|
||||
HIP_CHECK(hipMalloc(&Cd, LEN12));
|
||||
HIP_CHECK(hipMemcpy(Ad, A, LEN12, hipMemcpyHostToDevice));
|
||||
hipLaunchKernelGGL(MemCpy12, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Ad, Bd);
|
||||
hipLaunchKernelGGL(MemSet12, dim3(2, 1, 1), dim3(2, 1, 1), 0, 0, Cd);
|
||||
HIP_CHECK(hipMemcpy(B, Bd, LEN12, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipMemcpy(C, Cd, LEN12, hipMemcpyDeviceToHost));
|
||||
for (uint32_t i = 0; i < LEN12; i++) {
|
||||
REQUIRE(A[i] == B[i]);
|
||||
REQUIRE(C[i] == 1);
|
||||
}
|
||||
|
||||
delete[] A;
|
||||
delete[] B;
|
||||
delete[] C;
|
||||
HIP_CHECK(hipFree(Ad));
|
||||
HIP_CHECK(hipFree(Bd));
|
||||
HIP_CHECK(hipFree(Cd));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNNESS 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 INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
|
||||
#define NUM 1024
|
||||
#define THREADS_PER_BLOCK_X 4
|
||||
|
||||
// Device (Kernel) function, it must be void
|
||||
__global__ void vadd_asm(float* out, float* in) {
|
||||
int i = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
|
||||
#ifdef __HIP_PLATFORM_NVIDIA__
|
||||
asm volatile("add.f32 %0,%1,%2;" : "=f"(out[i]) : "f"(in[i]), "f"(out[i]));
|
||||
#endif
|
||||
|
||||
#ifdef __HIP_PLATFORM_AMD__
|
||||
asm volatile("v_add_f32_e32 %0, %1, %2" : "=v"(out[i]) : "v"(in[i]),
|
||||
"v"(out[i]));
|
||||
#endif
|
||||
}
|
||||
|
||||
// CPU implementation of Vector Result
|
||||
void addCPUReference(float* output, float* input) {
|
||||
for (unsigned int j = 0; j < NUM; j++) {
|
||||
output[j] = input[j] + output[j];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @addtogroup hipLaunchKernelGGL
|
||||
* @{
|
||||
* @ingroup KernelTest
|
||||
* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
|
||||
std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` -
|
||||
* Method to invocate kernel functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test case to check inline asm vadd instruction via kernel call.
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/kernel/inline_asm_vadd.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.6
|
||||
*/
|
||||
|
||||
TEST_CASE("Unit_kernel_inline_asm_vadd_Functional") {
|
||||
float* VectorA;
|
||||
float* ResultVector;
|
||||
float* VectorB;
|
||||
|
||||
float* gpuVector;
|
||||
float* gpuResultVector;
|
||||
|
||||
int i;
|
||||
int errors;
|
||||
|
||||
VectorA = reinterpret_cast<float*>(malloc(NUM * sizeof(float)));
|
||||
ResultVector = reinterpret_cast<float*>(malloc(NUM * sizeof(float)));
|
||||
VectorB = reinterpret_cast<float*>(malloc(NUM * sizeof(float)));
|
||||
|
||||
// initialize the input data
|
||||
for (i = 0; i < NUM; i++) {
|
||||
VectorA[i] = static_cast<float>(i * 10.0f);
|
||||
VectorB[i] = static_cast<float>(i * 30.0f);
|
||||
}
|
||||
|
||||
// allocate the memory on the device side
|
||||
HIP_CHECK(hipMalloc(reinterpret_cast<void**>(&gpuVector),
|
||||
NUM * sizeof(float)));
|
||||
HIP_CHECK(hipMalloc(reinterpret_cast<void**>(&gpuResultVector),
|
||||
NUM * sizeof(float)));
|
||||
|
||||
// Memory transfer from host to device
|
||||
HIP_CHECK(hipMemcpy(gpuVector, VectorA, NUM * sizeof(float),
|
||||
hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipMemcpy(gpuResultVector, VectorB, NUM * sizeof(float),
|
||||
hipMemcpyHostToDevice));
|
||||
|
||||
// Lauching kernel from host
|
||||
hipLaunchKernelGGL(vadd_asm, dim3(NUM / THREADS_PER_BLOCK_X),
|
||||
dim3(THREADS_PER_BLOCK_X), 0, 0,
|
||||
gpuResultVector, gpuVector);
|
||||
|
||||
// Memory transfer from device to host
|
||||
HIP_CHECK(hipMemcpy(ResultVector, gpuResultVector, NUM * sizeof(float),
|
||||
hipMemcpyDeviceToHost));
|
||||
|
||||
// CPU Result computation
|
||||
addCPUReference(VectorB, VectorA);
|
||||
|
||||
// verify the results
|
||||
errors = 0;
|
||||
double eps = 1.0E-3;
|
||||
for (i = 0; i < NUM; i++) {
|
||||
if (std::abs(ResultVector[i] - VectorB[i]) > eps) {
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
if (errors != 0) {
|
||||
REQUIRE(false);
|
||||
} else {
|
||||
REQUIRE(true);
|
||||
}
|
||||
|
||||
// free the resources on device side
|
||||
HIP_CHECK(hipFree(gpuVector));
|
||||
HIP_CHECK(hipFree(gpuResultVector));
|
||||
|
||||
HIP_CHECK(hipDeviceReset());
|
||||
|
||||
// free the resources on host side
|
||||
free(VectorA);
|
||||
free(ResultVector);
|
||||
free(VectorB);
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNNESS 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 INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
|
||||
#define NUM 1024
|
||||
#define THREADS_PER_BLOCK_X 4
|
||||
|
||||
// Device (Kernel) function, it must be void
|
||||
__global__ void vmac_asm(float* out, float* in, float a) {
|
||||
int i = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
asm volatile("v_mac_f32_e32 %0, %2, %3" : "=v"(out[i]) :
|
||||
"0"(out[i]), "v"(a), "v"(in[i]));
|
||||
}
|
||||
|
||||
// CPU implementation of saxpy
|
||||
void addCPUReference(float* output, float* input, float a) {
|
||||
for (unsigned int j = 0; j < NUM; j++) {
|
||||
output[j] = a * input[j] + output[j];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @addtogroup hipLaunchKernelGGL
|
||||
* @{
|
||||
* @ingroup KernelTest
|
||||
* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
|
||||
std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` -
|
||||
* Method to invocate kernel functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test case to check inline asm vmac instruction via kernel call.
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/kernel/inline_asm_vmac.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.6
|
||||
*/
|
||||
TEST_CASE("Unit_kernel_inline_asm_vmac_Functional") {
|
||||
float* VectorA;
|
||||
float* ResultVector;
|
||||
float* VectorB;
|
||||
|
||||
float* gpuVector;
|
||||
float* gpuResultVector;
|
||||
|
||||
const float a = 10.0f;
|
||||
int i;
|
||||
int errors;
|
||||
|
||||
VectorA = reinterpret_cast<float*>(malloc(NUM * sizeof(float)));
|
||||
ResultVector = reinterpret_cast<float*>(malloc(NUM * sizeof(float)));
|
||||
VectorB = reinterpret_cast<float*>(malloc(NUM * sizeof(float)));
|
||||
|
||||
// initialize the input data
|
||||
for (i = 0; i < NUM; i++) {
|
||||
VectorA[i] = static_cast<float>(i * 10.0f);
|
||||
VectorB[i] = static_cast<float>(i * 30.0f);
|
||||
}
|
||||
|
||||
// allocate the memory on the device side
|
||||
HIP_CHECK(hipMalloc(reinterpret_cast<void**>(&gpuVector),
|
||||
NUM * sizeof(float)));
|
||||
HIP_CHECK(hipMalloc(reinterpret_cast<void**>(&gpuResultVector),
|
||||
NUM * sizeof(float)));
|
||||
|
||||
// Memory transfer from host to device
|
||||
HIP_CHECK(hipMemcpy(gpuVector, VectorA, NUM * sizeof(float),
|
||||
hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipMemcpy(gpuResultVector, VectorB, NUM * sizeof(float),
|
||||
hipMemcpyHostToDevice));
|
||||
|
||||
// Lauching kernel from host
|
||||
hipLaunchKernelGGL(vmac_asm, dim3(NUM / THREADS_PER_BLOCK_X),
|
||||
dim3(THREADS_PER_BLOCK_X), 0, 0,
|
||||
gpuResultVector, gpuVector, a);
|
||||
|
||||
// Memory transfer from device to host
|
||||
HIP_CHECK(hipMemcpy(ResultVector, gpuResultVector, NUM * sizeof(float),
|
||||
hipMemcpyDeviceToHost));
|
||||
|
||||
// CPU Result computation
|
||||
addCPUReference(VectorB, VectorA, a);
|
||||
|
||||
// verify the results
|
||||
errors = 0;
|
||||
double eps = 1.0E-3;
|
||||
for (i = 0; i < NUM; i++) {
|
||||
if (std::abs(ResultVector[i] - VectorB[i]) > eps) {
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
if (errors != 0) {
|
||||
REQUIRE(false);
|
||||
} else {
|
||||
REQUIRE(true);
|
||||
}
|
||||
|
||||
// free the resources on device side
|
||||
HIP_CHECK(hipFree(gpuVector));
|
||||
HIP_CHECK(hipFree(gpuResultVector));
|
||||
HIP_CHECK(hipDeviceReset());
|
||||
|
||||
// free the resources on host side
|
||||
free(VectorA);
|
||||
free(ResultVector);
|
||||
free(VectorB);
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNNESS 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 INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
|
||||
constexpr size_t N = 1024;
|
||||
int p_blockSize = 256;
|
||||
|
||||
__global__ void
|
||||
__launch_bounds__(256, 2)
|
||||
myKern(int* C, const int* A, int N) {
|
||||
int tid = (blockIdx.x * blockDim.x + threadIdx.x);
|
||||
|
||||
if (tid < N) {
|
||||
C[tid] = A[tid];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @addtogroup hipLaunchKernelGGL
|
||||
* @{
|
||||
* @ingroup KernelTest
|
||||
* `void hipLaunchKernelGGL(F kernel, const dim3& numBlocks, const dim3& dimBlocks,
|
||||
std::uint32_t sharedMemBytes, hipStream_t stream, Args... args)` -
|
||||
* Method to invocate kernel functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Test case to check launch bounds via kernel call.
|
||||
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch/unit/kernel/launch_bounds.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.6
|
||||
*/
|
||||
|
||||
TEST_CASE("Unit_kernel_LaunchBounds_Functional") {
|
||||
size_t Nbytes = N * sizeof(int);
|
||||
int *A_d, *C_d, *A_h, *C_h;
|
||||
HIPCHECK(hipMalloc(&A_d, Nbytes));
|
||||
HIPCHECK(hipMalloc(&C_d, Nbytes));
|
||||
|
||||
A_h = reinterpret_cast<int*>(malloc(Nbytes));
|
||||
C_h = reinterpret_cast<int*>(malloc(Nbytes));
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
A_h[i] = i * 10;
|
||||
C_h[i] = 0x0;
|
||||
}
|
||||
int blocks = N / p_blockSize;
|
||||
|
||||
HIPCHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
|
||||
HIPCHECK(hipGetLastError());
|
||||
hipLaunchKernelGGL(myKern, dim3(blocks), dim3(p_blockSize), 0,
|
||||
0, C_d, A_d, N);
|
||||
|
||||
#ifdef __HIP_PLATFORM_NVIDIA__
|
||||
cudaFuncAttributes attrib;
|
||||
cudaFuncGetAttributes(&attrib, myKern);
|
||||
printf("binaryVersion = %d\n", attrib.binaryVersion);
|
||||
printf("cacheModeCA = %d\n", attrib.cacheModeCA);
|
||||
printf("constSizeBytes = %zu\n", attrib.constSizeBytes);
|
||||
printf("localSizeBytes = %zud\n", attrib.localSizeBytes);
|
||||
printf("maxThreadsPerBlock = %d\n", attrib.maxThreadsPerBlock);
|
||||
printf("numRegs = %d\n", attrib.numRegs);
|
||||
printf("ptxVersion = %d\n", attrib.ptxVersion);
|
||||
printf("sharedSizeBytes = %zud\n", attrib.sharedSizeBytes);
|
||||
#endif
|
||||
|
||||
HIPCHECK(hipDeviceSynchronize());
|
||||
HIPCHECK(hipGetLastError());
|
||||
HIPCHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
|
||||
HIPCHECK(hipDeviceSynchronize());
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
int goldVal = i * 10;
|
||||
REQUIRE(C_h[i] == goldVal);
|
||||
}
|
||||
HIP_CHECK(hipFree(A_d));
|
||||
HIP_CHECK(hipFree(C_d));
|
||||
free(A_h);
|
||||
free(C_h);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
Copyright (c) 2023 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.
|
||||
*/
|
||||
|
||||
#ifndef _STRESSTEST_PRINTF_COMMON_H_
|
||||
#define _STRESSTEST_PRINTF_COMMON_H_
|
||||
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <math.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
struct CaptureStream {
|
||||
int saved_fd;
|
||||
int orig_fd;
|
||||
int temp_fd;
|
||||
|
||||
char tempname[13] = "mytestXXXXXX";
|
||||
|
||||
explicit CaptureStream(FILE *original) {
|
||||
orig_fd = fileno(original);
|
||||
saved_fd = dup(orig_fd);
|
||||
|
||||
if ((temp_fd = mkstemp(tempname)) == -1) {
|
||||
error(0, errno, "Error");
|
||||
assert(false);
|
||||
}
|
||||
|
||||
fflush(nullptr);
|
||||
if (dup2(temp_fd, orig_fd) == -1) {
|
||||
error(0, errno, "Error");
|
||||
assert(false);
|
||||
}
|
||||
if (close(temp_fd) != 0) {
|
||||
error(0, errno, "Error");
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void restoreStream() {
|
||||
if (saved_fd == -1)
|
||||
return;
|
||||
fflush(nullptr);
|
||||
if (dup2(saved_fd, orig_fd) == -1) {
|
||||
error(0, errno, "Error");
|
||||
assert(false);
|
||||
}
|
||||
if (close(saved_fd) != 0) {
|
||||
error(0, errno, "Error");
|
||||
assert(false);
|
||||
}
|
||||
saved_fd = -1;
|
||||
}
|
||||
|
||||
const char *getTempFilename() {
|
||||
return (const char*)tempname;
|
||||
}
|
||||
|
||||
std::ifstream getCapturedData() {
|
||||
restoreStream();
|
||||
std::ifstream temp(tempname);
|
||||
return temp;
|
||||
}
|
||||
|
||||
~CaptureStream() {
|
||||
restoreStream();
|
||||
if (remove(tempname) != 0) {
|
||||
error(0, errno, "Error");
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _STRESSTEST_PRINTF_COMMON_H_
|
||||
@@ -18,9 +18,14 @@
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
# Common Tests - Test independent of all platforms
|
||||
set(COMMON_SHARED_SRC DriverContext.cc)
|
||||
|
||||
# Common Tests - Test independent of all platforms
|
||||
# FIXME: cjatin
|
||||
# This is a temp hack to pass it on windows since it has a char limit for
|
||||
# command line. Eventually we need to use rsp files with ninja on windows.
|
||||
# But this exposes several problems with hipcc and build system on windows.
|
||||
# While those are fixed, this hack should allow us to pass windows CI.
|
||||
set(TEST_SRC
|
||||
memset.cc
|
||||
malloc.cc
|
||||
@@ -63,7 +68,27 @@ set(TEST_SRC
|
||||
hipMemAdviseMmap.cc
|
||||
hipMallocManaged.cc
|
||||
hipMemRangeGetAttribute.cc
|
||||
hipMemRangeGetAttribute_old.cc
|
||||
hipMemRangeGetAttribute_old.cc)
|
||||
|
||||
if(HIP_PLATFORM MATCHES "amd")
|
||||
set(TEST_SRC
|
||||
${TEST_SRC}
|
||||
hipMemPtrGetInfo.cc
|
||||
hipPointerGetAttributes.cc
|
||||
hipMemCoherencyTst.cc
|
||||
hipExtMallocWithFlags.cc
|
||||
hipMallocMngdMultiThread.cc
|
||||
hipArray.cc
|
||||
hipMemVmm.cc)
|
||||
else()
|
||||
set(TEST_SRC ${TEST_SRC} hipGetSymbolSizeAddress.cc)
|
||||
endif()
|
||||
|
||||
hip_add_exe_to_target(NAME MemoryTest1
|
||||
TEST_SRC ${TEST_SRC}
|
||||
TEST_TARGET_NAME build_tests COMMON_SHARED_SRC ${COMMON_SHARED_SRC})
|
||||
|
||||
set(TEST_SRC
|
||||
hipMemcpyFromSymbol.cc
|
||||
hipPtrGetAttribute.cc
|
||||
hipMemPoolApi.cc
|
||||
@@ -83,6 +108,8 @@ set(TEST_SRC
|
||||
hipMemcpy_old.cc
|
||||
hipMemcpy_derivatives.cc
|
||||
hipMemcpyAsync.cc
|
||||
hipMemcpyAsync_old.cc
|
||||
hipMemcpyAsync_derivatives.cc
|
||||
hipMemsetFunctional.cc
|
||||
hipMalloc.cc
|
||||
hipMallocPitch.cc
|
||||
@@ -106,24 +133,12 @@ set(TEST_SRC
|
||||
hipMemAdvise_old.cc
|
||||
hipMemAdvise.cc
|
||||
hipMemRangeGetAttributes.cc
|
||||
hipFreeAsync.cc
|
||||
hipMallocAsync.cc
|
||||
hipStreamAttachMemAsync.cc
|
||||
hipMemRangeGetAttributes_old.cc
|
||||
hipMemGetAddressRange.cc)
|
||||
|
||||
if(HIP_PLATFORM MATCHES "amd")
|
||||
set(TEST_SRC
|
||||
${TEST_SRC}
|
||||
hipMemPtrGetInfo.cc
|
||||
hipPointerGetAttributes.cc
|
||||
hipMemCoherencyTst.cc
|
||||
hipExtMallocWithFlags.cc
|
||||
hipMallocMngdMultiThread.cc
|
||||
hipArray.cc
|
||||
hipMemVmm.cc)
|
||||
else()
|
||||
set(TEST_SRC ${TEST_SRC} hipGetSymbolSizeAddress.cc)
|
||||
endif()
|
||||
|
||||
hip_add_exe_to_target(NAME MemoryTest
|
||||
hip_add_exe_to_target(NAME MemoryTest2
|
||||
TEST_SRC ${TEST_SRC}
|
||||
TEST_TARGET_NAME build_tests COMMON_SHARED_SRC ${COMMON_SHARED_SRC})
|
||||
|
||||
@@ -49,11 +49,10 @@ using namespace std::chrono_literals;
|
||||
const std::chrono::duration<uint64_t, std::milli> delay = 50ms;
|
||||
constexpr size_t numAllocs = 10;
|
||||
|
||||
#if HT_AMD /* Disabled because frequency based wait is timing out on nvidia platforms */
|
||||
TEMPLATE_TEST_CASE("Unit_hipFreeImplicitSyncDev", "", char, float, float2, float4) {
|
||||
TestType* devPtr{};
|
||||
TEST_CASE("Unit_hipFreeImplicitSyncDev") {
|
||||
int* devPtr{};
|
||||
size_t size_mult = GENERATE(1, 32, 64, 128, 256);
|
||||
HIP_CHECK(hipMalloc(&devPtr, sizeof(TestType) * size_mult));
|
||||
HIP_CHECK(hipMalloc(&devPtr, sizeof(*devPtr) * size_mult));
|
||||
|
||||
HipTest::runKernelForDuration(delay);
|
||||
// make sure device is busy
|
||||
@@ -62,11 +61,11 @@ TEMPLATE_TEST_CASE("Unit_hipFreeImplicitSyncDev", "", char, float, float2, float
|
||||
HIP_CHECK(hipStreamQuery(nullptr));
|
||||
}
|
||||
|
||||
TEMPLATE_TEST_CASE("Unit_hipFreeImplicitSyncHost", "", char, float, float2, float4) {
|
||||
TestType* hostPtr{};
|
||||
TEST_CASE("Unit_hipFreeImplicitSyncHost") {
|
||||
int* hostPtr{};
|
||||
size_t size_mult = GENERATE(1, 32, 64, 128, 256);
|
||||
|
||||
HIP_CHECK(hipHostMalloc(&hostPtr, sizeof(TestType) * size_mult));
|
||||
HIP_CHECK(hipHostMalloc(&hostPtr, sizeof(*hostPtr) * size_mult));
|
||||
|
||||
HipTest::runKernelForDuration(delay);
|
||||
// make sure device is busy
|
||||
@@ -75,7 +74,7 @@ TEMPLATE_TEST_CASE("Unit_hipFreeImplicitSyncHost", "", char, float, float2, floa
|
||||
HIP_CHECK(hipStreamQuery(nullptr));
|
||||
}
|
||||
|
||||
#if HT_NVIDIA // Meaningless at the moment, since we are not running wait kernel on nvidia.
|
||||
#if HT_NVIDIA
|
||||
TEMPLATE_TEST_CASE("Unit_hipFreeImplicitSyncArray", "", char, float, float2, float4) {
|
||||
using vec_info = vector_info<TestType>;
|
||||
DriverContext ctx;
|
||||
@@ -135,7 +134,6 @@ TEMPLATE_TEST_CASE("Unit_hipFreeImplicitSyncArray", "", char, float, float2, flo
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Freeing a invalid pointer with on device
|
||||
@@ -166,8 +164,6 @@ TEST_CASE("Unit_hipFreeNegativeHost") {
|
||||
#if HT_NVIDIA
|
||||
TEST_CASE("Unit_hipFreeNegativeArray") {
|
||||
DriverContext ctx;
|
||||
hipArray_t arrayPtr{};
|
||||
hiparray cuArrayPtr{};
|
||||
|
||||
SECTION("ArrayFree") { HIP_CHECK(hipFreeArray(nullptr)); }
|
||||
SECTION("ArrayDestroy") {
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright (c) 2022 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 <hip_test_common.hh>
|
||||
|
||||
TEST_CASE("Unit_hipFreeAsync_negative") {
|
||||
HIP_CHECK(hipSetDevice(0));
|
||||
void* p = nullptr;
|
||||
hipStream_t stream{nullptr};
|
||||
hipStreamCreate(&stream);
|
||||
|
||||
SECTION("dev_ptr is nullptr") { REQUIRE(hipFreeAsync(nullptr, stream) != hipSuccess); }
|
||||
|
||||
SECTION("invalid stream handle") {
|
||||
HIP_CHECK(hipMallocAsync(static_cast<void**>(&p), 100, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
hipError_t error = hipFreeAsync(p, reinterpret_cast<hipStream_t>(-1));
|
||||
HIP_CHECK(hipFreeAsync(p, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
REQUIRE(error != hipSuccess);
|
||||
}
|
||||
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
HIP_CHECK(hipStreamDestroy(stream));
|
||||
}
|
||||
@@ -21,11 +21,19 @@ THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
#include <utils.hh>
|
||||
|
||||
TEST_CASE("Unit_hipHostGetDevicePointer_Negative") {
|
||||
int* hPtr{nullptr};
|
||||
int* dPtr{nullptr};
|
||||
HIP_CHECK(hipHostMalloc(&hPtr, sizeof(int)));
|
||||
|
||||
if (!DeviceAttributesSupport(0, hipDeviceAttributeCanMapHostMemory)) {
|
||||
HIP_CHECK_ERROR(hipHostGetDevicePointer(reinterpret_cast<void**>(&dPtr), hPtr, 0),
|
||||
hipErrorNotSupported);
|
||||
return;
|
||||
}
|
||||
|
||||
SECTION("Nullptr as device") {
|
||||
HIP_CHECK_ERROR(hipHostGetDevicePointer(nullptr, hPtr, 0), hipErrorInvalidValue);
|
||||
}
|
||||
@@ -36,13 +44,29 @@ TEST_CASE("Unit_hipHostGetDevicePointer_Negative") {
|
||||
hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
// Not adding check for flags since CUDA spec states that there might be more values added to it
|
||||
SECTION("Non pinned memory as host") {
|
||||
int* hPtr = reinterpret_cast<int*>(malloc(sizeof(*hPtr)));
|
||||
HIP_CHECK_ERROR(hipHostGetDevicePointer(reinterpret_cast<void**>(&dPtr), hPtr, 0),
|
||||
hipErrorInvalidValue);
|
||||
free(hPtr);
|
||||
}
|
||||
|
||||
SECTION("Flags non-zero") {
|
||||
HIP_CHECK_ERROR(hipHostGetDevicePointer(reinterpret_cast<void**>(&dPtr), hPtr, 1),
|
||||
hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
HIP_CHECK(hipHostFree(hPtr));
|
||||
}
|
||||
|
||||
template <typename T> __global__ void set(T* ptr, T val) { *ptr = val; }
|
||||
|
||||
TEST_CASE("Unit_hipHostGetDevicePointer_UseCase") {
|
||||
if(!DeviceAttributesSupport(0, hipDeviceAttributeCanMapHostMemory)) {
|
||||
HipTest::HIP_SKIP_TEST("Device does not support mapping host memory");
|
||||
return;
|
||||
}
|
||||
|
||||
int* hPtr{nullptr};
|
||||
HIP_CHECK(hipHostMalloc(&hPtr, sizeof(int)));
|
||||
|
||||
@@ -71,8 +95,8 @@ TEST_CASE("Unit_hipHostGetDevicePointer_UseCase") {
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
HIP_CHECK(hipHostUnregister(&res));
|
||||
|
||||
REQUIRE(value == 10);
|
||||
REQUIRE(res == value);
|
||||
}
|
||||
|
||||
HIP_CHECK(hipHostFree(hPtr));
|
||||
}
|
||||
}
|
||||
@@ -27,9 +27,10 @@ This testfile verifies the following scenarios of hipHostRegister API
|
||||
2. hipHostRegister and perform hipMemcpy on it.
|
||||
*/
|
||||
|
||||
#include "hip/hip_runtime_api.h"
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_helper.hh>
|
||||
#include "hip/hip_runtime_api.h"
|
||||
#include <utils.hh>
|
||||
|
||||
#define OFFSET 128
|
||||
static constexpr auto LEN{1024 * 1024};
|
||||
@@ -63,9 +64,7 @@ void doMemCopy(size_t numElements, int offset, T* A, T* Bh, T* Bd, bool internal
|
||||
HIP_CHECK(hipMemcpy(Bh, Bd, sizeBytes, hipMemcpyDeviceToHost));
|
||||
|
||||
// Make sure the copy worked
|
||||
for (size_t i = 0; i < numElements; i++) {
|
||||
REQUIRE(Bh[i] == A[i]);
|
||||
}
|
||||
ArrayMismatch(A, Bh, numElements);
|
||||
|
||||
if (internalRegister) {
|
||||
HIP_CHECK(hipHostUnregister(A));
|
||||
|
||||
@@ -68,6 +68,12 @@ TEST_CASE("Unit_hipHostUnregister_NullPtr") {
|
||||
HIP_CHECK_ERROR(hipHostUnregister(nullptr), hipErrorInvalidValue);
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipHostUnregister_Ptr_Different_Than_Specified_To_Register") {
|
||||
std::vector<int> alloc(2);
|
||||
HIP_CHECK(hipHostRegister(alloc.data(), alloc.size(), 0));
|
||||
HIP_CHECK_ERROR(hipHostUnregister(&alloc.data()[1]), hipErrorHostMemoryNotRegistered);
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipHostUnregister_NotRegisteredPointer") {
|
||||
auto x = std::unique_ptr<int>(new int);
|
||||
HIP_CHECK_ERROR(hipHostUnregister(x.get()), hipErrorHostMemoryNotRegistered);
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright (c) 2022 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 WARRANNTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INNCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANNY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER INN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR INN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_checkers.hh>
|
||||
|
||||
#include <limits>
|
||||
|
||||
TEST_CASE("Unit_hipMallocAsync_negative") {
|
||||
HIP_CHECK(hipSetDevice(0));
|
||||
|
||||
void* p = nullptr;
|
||||
size_t max_size = std::numeric_limits<size_t>::max();
|
||||
hipStream_t stream{nullptr};
|
||||
HIP_CHECK(hipStreamCreate(&stream));
|
||||
|
||||
|
||||
SECTION("Device pointer is null") { REQUIRE(hipMallocAsync(nullptr, 100, stream) != hipSuccess); }
|
||||
|
||||
SECTION("stream is invalid") {
|
||||
REQUIRE(hipMallocAsync(static_cast<void**>(&p), 100, reinterpret_cast<hipStream_t>(-1)) !=
|
||||
hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("out of memory") {
|
||||
REQUIRE(hipMallocAsync(static_cast<void**>(&p), max_size, stream) != hipSuccess);
|
||||
}
|
||||
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
HIP_CHECK(hipStreamDestroy(stream));
|
||||
}
|
||||
@@ -228,6 +228,21 @@ TEST_CASE("Unit_hipMallocPitch_Negative") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMallocPitch_Zero_Dims") {
|
||||
void* ptr = nullptr;
|
||||
size_t pitch = 0;
|
||||
|
||||
SECTION("width == 0") {
|
||||
HIP_CHECK(hipMallocPitch(&ptr, &pitch, 0, 1));
|
||||
REQUIRE(ptr == nullptr);
|
||||
}
|
||||
|
||||
SECTION("height == 0") {
|
||||
HIP_CHECK(hipMallocPitch(&ptr, &pitch, 1, 0));
|
||||
REQUIRE(ptr == nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemAllocPitch_Negative") {
|
||||
size_t pitch = 0;
|
||||
hipDeviceptr_t ptr{};
|
||||
@@ -360,42 +375,7 @@ static void MemoryAllocDiffSizes(int gpu) {
|
||||
static void threadFunc(int gpu) {
|
||||
MemoryAllocDiffSizes<float>(gpu);
|
||||
}
|
||||
/*
|
||||
* This testcase verifies the negative scenarios of hipMallocPitch API
|
||||
*/
|
||||
#if 0 //TODO: Review, fix and re-enable test
|
||||
TEST_CASE("Unit_hipMallocPitch_Negative") {
|
||||
float* A_d;
|
||||
size_t pitch_A = 0;
|
||||
size_t width{NUM_W * sizeof(float)};
|
||||
#if HT_NVIDIA
|
||||
SECTION("NullPtr to Pitched Ptr") {
|
||||
REQUIRE(hipMallocPitch(nullptr,
|
||||
&pitch_A, width, NUM_H) != hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("nullptr to pitch") {
|
||||
REQUIRE(hipMallocPitch(reinterpret_cast<void**>(&A_d),
|
||||
nullptr, width, NUM_H) != hipSuccess);
|
||||
}
|
||||
#endif
|
||||
SECTION("Width 0 in hipMallocPitch") {
|
||||
REQUIRE(hipMallocPitch(reinterpret_cast<void**>(&A_d),
|
||||
&pitch_A, 0, NUM_H) == hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("Height 0 in hipMallocPitch") {
|
||||
REQUIRE(hipMallocPitch(reinterpret_cast<void**>(&A_d),
|
||||
&pitch_A, width, 0) == hipSuccess);
|
||||
}
|
||||
|
||||
SECTION("Max int values") {
|
||||
REQUIRE(hipMallocPitch(reinterpret_cast<void**>(&A_d),
|
||||
&pitch_A, std::numeric_limits<int>::max(),
|
||||
std::numeric_limits<int>::max()) != hipSuccess);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* This testcase verifies the basic scenario of
|
||||
* hipMallocPitch API for different datatypes
|
||||
@@ -408,6 +388,7 @@ TEMPLATE_TEST_CASE("Unit_hipMallocPitch_Basic",
|
||||
size_t width{NUM_W * sizeof(TestType)};
|
||||
REQUIRE(hipMallocPitch(reinterpret_cast<void**>(&A_d),
|
||||
&pitch_A, width, NUM_H) == hipSuccess);
|
||||
REQUIRE(width <= pitch_A);
|
||||
HIP_CHECK(hipFree(A_d));
|
||||
}
|
||||
|
||||
@@ -538,4 +519,3 @@ TEMPLATE_TEST_CASE("Unit_hipMallocPitch_KernelLaunch", ""
|
||||
HipTest::freeArrays<TestType>(nullptr, nullptr, nullptr,
|
||||
A_h, B_h, C_h, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -652,87 +652,54 @@ TEST_CASE("Unit_hipMemAdvise_TstAccessedByFlg4") {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Allocate memory using aligned_alloc(), assign PreferredLocation flag to
|
||||
the allocated memory and launch a kernel. Kernel should get executed
|
||||
successfully without hang or segfault*/
|
||||
#if __linux__ && HT_AMD
|
||||
TEST_CASE("Unit_hipMemAdvise_TstAlignedAllocMem") {
|
||||
if ((setenv("HSA_XNACK", "1", 1)) != 0) {
|
||||
WARN("Unable to turn on HSA_XNACK, hence terminating the Test case!");
|
||||
REQUIRE(false);
|
||||
}
|
||||
// The following code block checks for gfx90a,940,941,942 so as to skip if the device is not
|
||||
|
||||
// The following code block checks for xnack+
|
||||
// so as to skip if the device is not xnack+
|
||||
hipDeviceProp_t prop;
|
||||
int device;
|
||||
HIP_CHECK(hipGetDevice(&device));
|
||||
HIP_CHECK(hipGetDeviceProperties(&prop, device));
|
||||
std::string gfxName(prop.gcnArchName);
|
||||
|
||||
if (CheckIfFeatSupported(CTFeatures::CT_FEATURE_HMM, prop.gcnArchName)) {
|
||||
if (gfxName.find("xnack+") != std::string::npos) {
|
||||
int stat = 0;
|
||||
if (fork() == 0) {
|
||||
// The below part should be inside fork
|
||||
int managedMem = 0, pageMemAccess = 0;
|
||||
HIP_CHECK(hipDeviceGetAttribute(&pageMemAccess,
|
||||
hipDeviceAttributePageableMemoryAccess, 0));
|
||||
WARN("hipDeviceAttributePageableMemoryAccess:" << pageMemAccess);
|
||||
|
||||
HIP_CHECK(hipDeviceGetAttribute(&managedMem, hipDeviceAttributeManagedMemory, 0));
|
||||
WARN("hipDeviceAttributeManagedMemory: " << managedMem);
|
||||
if ((managedMem == 1) && (pageMemAccess == 1)) {
|
||||
int *Mllc = nullptr, MemSz = 4096 * 4, NumElms = 4096, InitVal = 123;
|
||||
// Mllc = reinterpret_cast<(int *)>(aligned_alloc(4096, MemSz));
|
||||
Mllc = reinterpret_cast<int*>(aligned_alloc(4096, 4096*4));
|
||||
for (int i = 0; i < NumElms; ++i) {
|
||||
Mllc[i] = InitVal;
|
||||
}
|
||||
hipStream_t strm;
|
||||
int DataMismatch = 0;
|
||||
HIP_CHECK(hipStreamCreate(&strm));
|
||||
// The following hipMemAdvise() call is made to know if advise on
|
||||
// aligned_alloc() is causing any issue
|
||||
HIP_CHECK(hipMemAdvise(Mllc, MemSz, hipMemAdviseSetPreferredLocation, 0));
|
||||
HIP_CHECK(hipMemPrefetchAsync(Mllc, MemSz, 0, strm));
|
||||
HIP_CHECK(hipStreamSynchronize(strm));
|
||||
MemAdvise2<<<(NumElms/32), 32, 0, strm>>>(Mllc, NumElms);
|
||||
HIP_CHECK(hipStreamSynchronize(strm));
|
||||
int managedMem = 0, pageMemAccess = 0;
|
||||
HIP_CHECK(hipDeviceGetAttribute(&pageMemAccess,
|
||||
hipDeviceAttributePageableMemoryAccess, 0));
|
||||
WARN("hipDeviceAttributePageableMemoryAccess:" << pageMemAccess);
|
||||
HIP_CHECK(hipDeviceGetAttribute(&managedMem, hipDeviceAttributeManagedMemory, 0));
|
||||
WARN("hipDeviceAttributeManagedMemory: " << managedMem);
|
||||
if ((managedMem == 1) && (pageMemAccess == 1)) {
|
||||
int *Mllc = nullptr, MemSz = 4096 * 4, NumElms = 4096, InitVal = 123;
|
||||
// Mllc = reinterpret_cast<(int *)>(aligned_alloc(4096, MemSz));
|
||||
Mllc = reinterpret_cast<int*>(aligned_alloc(4096, 4096*4));
|
||||
for (int i = 0; i < NumElms; ++i) {
|
||||
Mllc[i] = InitVal;
|
||||
}
|
||||
hipStream_t strm;
|
||||
int DataMismatch = 0;
|
||||
HIP_CHECK(hipStreamCreate(&strm));
|
||||
// The following hipMemAdvise() call is made to know if advise on
|
||||
// aligned_alloc() is causing any issue
|
||||
HIP_CHECK(hipMemAdvise(Mllc, MemSz, hipMemAdviseSetPreferredLocation, 0));
|
||||
HIP_CHECK(hipMemPrefetchAsync(Mllc, MemSz, 0, strm));
|
||||
HIP_CHECK(hipStreamSynchronize(strm));
|
||||
MemAdvise2<<<(NumElms/32), 32, 0, strm>>>(Mllc, NumElms);
|
||||
HIP_CHECK(hipStreamSynchronize(strm));
|
||||
for (int i = 0; i < NumElms; ++i) {
|
||||
if (Mllc[i] != (InitVal + 10)) {
|
||||
DataMismatch++;
|
||||
}
|
||||
}
|
||||
if (DataMismatch != 0) {
|
||||
WARN("DataMismatch observed!!");
|
||||
exit(9); // 9 for failure
|
||||
} else {
|
||||
exit(10); // 10 for Pass result
|
||||
}
|
||||
} else {
|
||||
SUCCEED("GPU 0 doesn't support ManagedMemory with hipDeviceAttributePageableMemoryAccess "
|
||||
"attribute. Hence skipping the testing with Pass result.\n");
|
||||
exit(Catch::ResultDisposition::ContinueOnFailure);
|
||||
}
|
||||
} else {
|
||||
wait(&stat);
|
||||
int Result = WEXITSTATUS(stat);
|
||||
if (Result == Catch::ResultDisposition::ContinueOnFailure) {
|
||||
WARN("GPU 0 doesn't support ManagedMemory with hipDeviceAttributePageableMemoryAccess "
|
||||
"attribute. Hence skipping the testing with Pass result.\n");
|
||||
} else {
|
||||
if (Result != 10) {
|
||||
REQUIRE(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
REQUIRE(DataMismatch == 0);
|
||||
}
|
||||
} else {
|
||||
SUCCEED("Memory model feature is only supported for gfx90a, gfx940, gx941, gfx942, Hence"
|
||||
"skipping the testcase for this GPU " << device);
|
||||
WARN("Memory model feature is only supported for gfx90a, gfx940, gx941, gfx942, Hence"
|
||||
"skipping the testcase for this GPU " << device);
|
||||
}
|
||||
|
||||
HipTest::HIP_SKIP_TEST("GPU is not xnack enabled hence skipping the test...\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
/*
|
||||
Copyright (c) 2022 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
Copyright (c) 2022 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
|
||||
@@ -17,392 +19,145 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
This testcase verifies the following scenarios
|
||||
1. hipMemcpyAsync with kernel launch
|
||||
2. H2D-D2D-D2H-H2PinnMem and device context change scenarios
|
||||
3. This test launches multiple threads which uses same stream to deploy kernel
|
||||
and also launch hipMemcpyAsync() api. This test case is simulate the scenario
|
||||
reported in SWDEV-181598.
|
||||
*/
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_kernels.hh>
|
||||
#include <hip_test_checkers.hh>
|
||||
#include <atomic>
|
||||
#include <hip/hip_runtime_api.h>
|
||||
#include <memcpy1d_tests_common.hh>
|
||||
#include <resource_guards.hh>
|
||||
#include <utils.hh>
|
||||
|
||||
#define NUM_THREADS 16
|
||||
TEST_CASE("Unit_hipMemcpyAsync_Positive_Basic") {
|
||||
using namespace std::placeholders;
|
||||
const auto stream_type = GENERATE(Streams::nullstream, Streams::perThread, Streams::created);
|
||||
const StreamGuard stream_guard(stream_type);
|
||||
const hipStream_t stream = stream_guard.stream();
|
||||
|
||||
static constexpr auto NUM_ELM{1024 * 1024};
|
||||
|
||||
|
||||
|
||||
static constexpr size_t N_ELMTS{32 * 1024};
|
||||
std::atomic<size_t> Thread_count { 0 };
|
||||
static unsigned blocksPerCU{6}; // to hide latency
|
||||
static unsigned threadsPerBlock{256};
|
||||
|
||||
template<typename T>
|
||||
void Thread_func(T *A_d, T *B_d, T* C_d, T* C_h, size_t Nbytes,
|
||||
hipStream_t mystream) {
|
||||
unsigned blocks = HipTest::setNumBlocks(blocksPerCU,
|
||||
threadsPerBlock, N_ELMTS);
|
||||
hipLaunchKernelGGL(HipTest::vector_square, dim3(blocks),
|
||||
dim3(threadsPerBlock), 0,
|
||||
mystream, A_d, C_d, N_ELMTS);
|
||||
HIP_CHECK(hipGetLastError());
|
||||
HIP_CHECK(hipMemcpyAsync(C_h, C_d, Nbytes, hipMemcpyDeviceToHost, mystream));
|
||||
// The following two MemcpyAsync calls are for sole
|
||||
// purpose of loading stream with multiple async calls
|
||||
HIP_CHECK(hipMemcpyAsync(B_d, A_d, Nbytes,
|
||||
hipMemcpyDeviceToDevice, mystream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_d, A_d, Nbytes,
|
||||
hipMemcpyDeviceToDevice, mystream));
|
||||
Thread_count++;
|
||||
MemcpyWithDirectionCommonTests<true>(std::bind(hipMemcpyAsync, _1, _2, _3, _4, stream));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Thread_func_MultiStream() {
|
||||
int Data_mismatch = 0;
|
||||
T *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr};
|
||||
T *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr};
|
||||
size_t Nbytes = N_ELMTS * sizeof(T);
|
||||
unsigned blocks = HipTest::setNumBlocks(blocksPerCU,
|
||||
threadsPerBlock, N_ELMTS);
|
||||
|
||||
HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N_ELMTS, false);
|
||||
hipStream_t mystream;
|
||||
HIP_CHECK(hipStreamCreateWithFlags(&mystream, hipStreamNonBlocking));
|
||||
HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice, mystream));
|
||||
hipLaunchKernelGGL((HipTest::vector_square), dim3(blocks),
|
||||
dim3(threadsPerBlock), 0,
|
||||
mystream, A_d, C_d, N_ELMTS);
|
||||
HIP_CHECK(hipGetLastError());
|
||||
HIP_CHECK(hipMemcpyAsync(C_h, C_d, Nbytes, hipMemcpyDeviceToHost, mystream));
|
||||
// The following hipMemcpyAsync() is called only to
|
||||
// load stream with multiple Async calls
|
||||
HIP_CHECK(hipMemcpyAsync(B_d, A_d, Nbytes,
|
||||
hipMemcpyDeviceToDevice, mystream));
|
||||
Thread_count++;
|
||||
TEST_CASE("Unit_hipMemcpyAsync_Positive_Synchronization_Behavior") {
|
||||
using namespace std::placeholders;
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
HIP_CHECK(hipStreamSynchronize(mystream));
|
||||
HIP_CHECK(hipStreamDestroy(mystream));
|
||||
// Verifying result of the kernel computation
|
||||
for (size_t i = 0; i < N_ELMTS; i++) {
|
||||
if (C_h[i] != A_h[i] * A_h[i]) {
|
||||
Data_mismatch++;
|
||||
}
|
||||
}
|
||||
// Releasing resources
|
||||
HipTest::freeArrays<T>(A_d, B_d, C_d, A_h, B_h, C_h, false);
|
||||
REQUIRE(Data_mismatch == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
This testcase verifies hipMemcpyAsync API
|
||||
Initializes device variables
|
||||
Launches kernel and performs the sum of device variables
|
||||
copies the result to host variable and validates the result.
|
||||
*/
|
||||
TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_KernelLaunch", "", int, float,
|
||||
double) {
|
||||
size_t Nbytes = NUM_ELM * sizeof(TestType);
|
||||
|
||||
TestType *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr};
|
||||
TestType *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr};
|
||||
HIP_CHECK(hipSetDevice(0));
|
||||
hipStream_t stream;
|
||||
HIP_CHECK(hipStreamCreate(&stream));
|
||||
|
||||
HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, NUM_ELM, false);
|
||||
|
||||
HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_d, B_h, Nbytes, hipMemcpyHostToDevice, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
|
||||
hipLaunchKernelGGL(HipTest::vectorADD, dim3(1), dim3(1), 0, 0,
|
||||
static_cast<const TestType*>(A_d),
|
||||
static_cast<const TestType*>(B_d), C_d, NUM_ELM);
|
||||
HIP_CHECK(hipGetLastError());
|
||||
HIP_CHECK(hipMemcpyAsync(C_h, C_d, Nbytes, hipMemcpyDeviceToHost, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
HIP_CHECK(hipStreamDestroy(stream));
|
||||
|
||||
HipTest::checkVectorADD(A_h, B_h, C_h, NUM_ELM);
|
||||
|
||||
HipTest::freeArrays<TestType>(A_d, B_d, C_d, A_h, B_h, C_h, false);
|
||||
}
|
||||
/*
|
||||
This testcase verifies the following scenarios
|
||||
1. H2H,H2PinMem and PinnedMem2Host
|
||||
2. H2D-D2D-D2H in same GPU
|
||||
3. Pinned Host Memory to device variables in same GPU
|
||||
4. Device context change
|
||||
5. H2D-D2D-D2H peer GPU
|
||||
*/
|
||||
TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_H2H-H2D-D2H-H2PinMem", "", char, int,
|
||||
float, double) {
|
||||
TestType *A_d{nullptr}, *B_d{nullptr};
|
||||
TestType *A_h{nullptr}, *B_h{nullptr};
|
||||
TestType *A_Ph{nullptr}, *B_Ph{nullptr};
|
||||
HIP_CHECK(hipSetDevice(0));
|
||||
hipStream_t stream;
|
||||
HIP_CHECK(hipStreamCreate(&stream));
|
||||
HipTest::initArrays<TestType>(&A_d, &B_d, nullptr,
|
||||
&A_h, &B_h, nullptr,
|
||||
NUM_ELM*sizeof(TestType));
|
||||
HipTest::initArrays<TestType>(nullptr, nullptr, nullptr,
|
||||
&A_Ph, &B_Ph, nullptr,
|
||||
NUM_ELM*sizeof(TestType), true);
|
||||
|
||||
SECTION("H2H, H2PinMem and PinMem2H") {
|
||||
HIP_CHECK(hipMemcpyAsync(B_h, A_h, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyHostToHost, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(A_Ph, B_h, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyHostToHost, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_Ph, A_Ph, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyHostToHost, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
HipTest::checkTest(A_h, B_Ph, NUM_ELM);
|
||||
SECTION("Host memory to device memory") {
|
||||
// This behavior differs on NVIDIA and AMD, on AMD the hipMemcpy calls is synchronous with
|
||||
// respect to the host
|
||||
#if HT_AMD
|
||||
HipTest::HIP_SKIP_TEST(
|
||||
"EXSWCPHIPT-127 - MemcpyAsync from host to device memory behavior differs on AMD and "
|
||||
"Nvidia");
|
||||
return;
|
||||
#endif
|
||||
MemcpyHtoDSyncBehavior(std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyHostToDevice, nullptr),
|
||||
false);
|
||||
}
|
||||
|
||||
SECTION("H2D-D2D-D2H-SameGPU") {
|
||||
HIP_CHECK(hipMemcpyAsync(A_d, A_h, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyHostToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_d, A_d, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyDeviceToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_h, B_d, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyDeviceToHost, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
HipTest::checkTest(A_h, B_h, NUM_ELM);
|
||||
SECTION("Device memory to pageable host memory") {
|
||||
MemcpyDtoHPageableSyncBehavior(
|
||||
std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyDeviceToHost, nullptr), true);
|
||||
}
|
||||
|
||||
SECTION("pH2D-D2D-D2pH-SameGPU") {
|
||||
HIP_CHECK(hipMemcpyAsync(A_d, A_Ph, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyHostToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_d, A_d, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyDeviceToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_Ph, B_d, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyDeviceToHost, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
HipTest::checkTest(A_Ph, B_Ph, NUM_ELM);
|
||||
}
|
||||
SECTION("H2D-D2D-D2H-DeviceContextChange") {
|
||||
int deviceCount = 0;
|
||||
HIP_CHECK(hipGetDeviceCount(&deviceCount));
|
||||
if (deviceCount < 2) {
|
||||
SUCCEED("deviceCount less then 2");
|
||||
} else {
|
||||
int canAccessPeer = 0;
|
||||
HIP_CHECK(hipDeviceCanAccessPeer(&canAccessPeer, 0, 1));
|
||||
if (canAccessPeer) {
|
||||
HIP_CHECK(hipSetDevice(1));
|
||||
HIP_CHECK(hipMemcpyAsync(A_d, A_h, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyHostToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_d, A_d, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyDeviceToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_h, B_d, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyDeviceToHost, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
HipTest::checkTest(A_h, B_h, NUM_ELM);
|
||||
|
||||
} else {
|
||||
SUCCEED("P2P capability is not present");
|
||||
}
|
||||
}
|
||||
SECTION("Device memory to pinned host memory") {
|
||||
MemcpyDtoHPinnedSyncBehavior(
|
||||
std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyDeviceToHost, nullptr), false);
|
||||
}
|
||||
|
||||
SECTION("H2D-D2D-D2H-PeerGPU") {
|
||||
int deviceCount = 0;
|
||||
HIP_CHECK(hipGetDeviceCount(&deviceCount));
|
||||
if (deviceCount < 2) {
|
||||
SUCCEED("deviceCount less then 2");
|
||||
} else {
|
||||
int canAccessPeer = 0;
|
||||
HIP_CHECK(hipDeviceCanAccessPeer(&canAccessPeer, 0, 1));
|
||||
if (canAccessPeer) {
|
||||
HIP_CHECK(hipSetDevice(1));
|
||||
TestType *C_d{nullptr};
|
||||
HipTest::initArrays<TestType>(nullptr, nullptr, &C_d,
|
||||
nullptr, nullptr, nullptr,
|
||||
NUM_ELM*sizeof(TestType));
|
||||
HIP_CHECK(hipMemcpyAsync(A_d, A_h, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyHostToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(C_d, A_d, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyDeviceToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_h, C_d, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyDeviceToHost, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
HipTest::checkTest(A_h, B_h, NUM_ELM);
|
||||
HIP_CHECK(hipFree(C_d));
|
||||
|
||||
} else {
|
||||
SUCCEED("P2P capability is not present");
|
||||
}
|
||||
}
|
||||
SECTION("Device memory to device memory") {
|
||||
MemcpyDtoDSyncBehavior(std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyDeviceToDevice, nullptr),
|
||||
false);
|
||||
}
|
||||
|
||||
HIP_CHECK(hipStreamDestroy(stream));
|
||||
|
||||
HipTest::freeArrays<TestType>(A_d, B_d, nullptr, A_h, B_h, nullptr, false);
|
||||
HipTest::freeArrays<TestType>(nullptr, nullptr, nullptr, A_Ph,
|
||||
B_Ph, nullptr, true);
|
||||
}
|
||||
|
||||
// This test launches multiple threads which uses same stream to deploy kernel
|
||||
// and also launch hipMemcpyAsync() api. This test case is simulate the scenario
|
||||
// reported in SWDEV-181598
|
||||
|
||||
TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_hipMultiMemcpyMultiThread", "",
|
||||
int, float, double) {
|
||||
size_t Nbytes = N_ELMTS * sizeof(TestType);
|
||||
|
||||
int Data_mismatch = 0;
|
||||
hipStream_t mystream;
|
||||
TestType *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr};
|
||||
TestType *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr};
|
||||
|
||||
HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N_ELMTS, false);
|
||||
|
||||
HIP_CHECK(hipStreamCreateWithFlags(&mystream, hipStreamNonBlocking));
|
||||
HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice, mystream));
|
||||
|
||||
std::thread T[NUM_THREADS];
|
||||
for (int i = 0; i < NUM_THREADS; i++) {
|
||||
T[i] = std::thread(Thread_func<TestType>, A_d, B_d, C_d,
|
||||
C_h, Nbytes, mystream);
|
||||
}
|
||||
|
||||
// Wait until all the threads finish their execution
|
||||
for (int i = 0; i < NUM_THREADS; i++) {
|
||||
T[i].join();
|
||||
}
|
||||
|
||||
HIP_CHECK(hipStreamSynchronize(mystream));
|
||||
HIP_CHECK(hipStreamDestroy(mystream));
|
||||
|
||||
// Verifying the result of the kernel computation
|
||||
for (size_t i = 0; i < N_ELMTS; i++) {
|
||||
if (C_h[i] != A_h[i] * A_h[i]) {
|
||||
Data_mismatch++;
|
||||
}
|
||||
}
|
||||
REQUIRE(Thread_count.load() == NUM_THREADS);
|
||||
REQUIRE(Data_mismatch == 0);
|
||||
HipTest::freeArrays<TestType>(A_d, B_d, C_d, A_h, B_h, C_h, false);
|
||||
Thread_count.exchange(0);
|
||||
}
|
||||
|
||||
TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_hipMultiMemcpyMultiThreadMultiStream",
|
||||
"", int, float, double) {
|
||||
std::thread T[NUM_THREADS];
|
||||
for (int i = 0; i < NUM_THREADS; i++) {
|
||||
T[i] = std::thread(Thread_func_MultiStream<TestType>);
|
||||
}
|
||||
|
||||
// Wait until all the threads finish their execution
|
||||
for (int i = 0; i < NUM_THREADS; i++) {
|
||||
T[i].join();
|
||||
}
|
||||
|
||||
REQUIRE(Thread_count.load() == NUM_THREADS);
|
||||
Thread_count.exchange(0);
|
||||
}
|
||||
|
||||
/*
|
||||
This testcase verifies hipMemcpy API with pinnedMemory and hostRegister
|
||||
along with kernel launches
|
||||
*/
|
||||
|
||||
TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_PinnedRegMemWithKernelLaunch",
|
||||
"", int, float, double) {
|
||||
int numDevices = 0;
|
||||
HIP_CHECK(hipGetDeviceCount(&numDevices));
|
||||
if (numDevices < 2) {
|
||||
SUCCEED("No of devices are less than 2");
|
||||
} else {
|
||||
// 1 refers to pinned Memory
|
||||
// 2 refers to register Memory
|
||||
int MallocPinType = GENERATE(0, 1);
|
||||
size_t Nbytes = NUM_ELM * sizeof(TestType);
|
||||
unsigned blocks = HipTest::setNumBlocks(blocksPerCU,
|
||||
threadsPerBlock, NUM_ELM);
|
||||
|
||||
TestType *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr};
|
||||
TestType *X_d{nullptr}, *Y_d{nullptr}, *Z_d{nullptr};
|
||||
TestType *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr};
|
||||
if (MallocPinType) {
|
||||
HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, NUM_ELM, true);
|
||||
} else {
|
||||
A_h = reinterpret_cast<TestType*>(malloc(Nbytes));
|
||||
HIP_CHECK(hipHostRegister(A_h, Nbytes, hipHostRegisterDefault));
|
||||
B_h = reinterpret_cast<TestType*>(malloc(Nbytes));
|
||||
HIP_CHECK(hipHostRegister(B_h, Nbytes, hipHostRegisterDefault));
|
||||
C_h = reinterpret_cast<TestType*>(malloc(Nbytes));
|
||||
HIP_CHECK(hipHostRegister(C_h, Nbytes, hipHostRegisterDefault));
|
||||
HipTest::initArrays<TestType>(&A_d, &B_d, &C_d, nullptr, nullptr,
|
||||
nullptr, NUM_ELM, false);
|
||||
HipTest::setDefaultData<TestType>(NUM_ELM, A_h, B_h, C_h);
|
||||
}
|
||||
HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice));
|
||||
|
||||
hipLaunchKernelGGL(HipTest::vectorADD, dim3(blocks), dim3(threadsPerBlock),
|
||||
0, 0, static_cast<const TestType*>(A_d),
|
||||
static_cast<const TestType*>(B_d), C_d, NUM_ELM);
|
||||
HIP_CHECK(hipGetLastError());
|
||||
HIP_CHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
|
||||
HipTest::checkVectorADD(A_h, B_h, C_h, NUM_ELM);
|
||||
|
||||
unsigned int seed = time(0);
|
||||
HIP_CHECK(hipSetDevice(HipTest::RAND_R(&seed) % (numDevices-1)+1));
|
||||
|
||||
int device;
|
||||
HIP_CHECK(hipGetDevice(&device));
|
||||
INFO("hipMemcpy is set to happen between device 0 and device "
|
||||
<< device);
|
||||
HipTest::initArrays<TestType>(&X_d, &Y_d, &Z_d, nullptr,
|
||||
nullptr, nullptr, NUM_ELM, false);
|
||||
|
||||
hipStream_t gpu1Stream;
|
||||
HIP_CHECK(hipStreamCreate(&gpu1Stream));
|
||||
|
||||
for (int j = 0; j < NUM_ELM; j++) {
|
||||
A_h[j] = 0;
|
||||
B_h[j] = 0;
|
||||
C_h[j] = 0;
|
||||
}
|
||||
|
||||
HIP_CHECK(hipMemcpy(A_h, A_d, Nbytes, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipMemcpyAsync(X_d, A_h, Nbytes, hipMemcpyHostToDevice, gpu1Stream));
|
||||
HIP_CHECK(hipMemcpy(B_h, B_d, Nbytes, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipMemcpyAsync(Y_d, B_h, Nbytes, hipMemcpyHostToDevice, gpu1Stream));
|
||||
|
||||
hipLaunchKernelGGL(HipTest::vectorADD, dim3(blocks), dim3(threadsPerBlock),
|
||||
0, 0, static_cast<const TestType*>(X_d),
|
||||
static_cast<const TestType*>(Y_d), Z_d, NUM_ELM);
|
||||
HIP_CHECK(hipGetLastError());
|
||||
HIP_CHECK(hipMemcpyAsync(C_h, Z_d, Nbytes,
|
||||
hipMemcpyDeviceToHost, gpu1Stream));
|
||||
HIP_CHECK(hipStreamSynchronize(gpu1Stream));
|
||||
|
||||
HipTest::checkVectorADD(A_h, B_h, C_h, NUM_ELM);
|
||||
|
||||
if (MallocPinType) {
|
||||
HipTest::freeArrays<TestType>(A_d, B_d, C_d, A_h, B_h, C_h, true);
|
||||
} else {
|
||||
HIP_CHECK(hipHostUnregister(A_h));
|
||||
free(A_h);
|
||||
HIP_CHECK(hipHostUnregister(B_h));
|
||||
free(B_h);
|
||||
HIP_CHECK(hipHostUnregister(C_h));
|
||||
free(C_h);
|
||||
HipTest::freeArrays<TestType>(A_d, B_d, C_d, nullptr,
|
||||
nullptr, nullptr, false);
|
||||
}
|
||||
HipTest::freeArrays<TestType>(X_d, Y_d, Z_d, nullptr,
|
||||
nullptr, nullptr, false);
|
||||
HIP_CHECK(hipStreamDestroy(gpu1Stream));
|
||||
SECTION("Host memory to host memory") {
|
||||
MemcpyHtoHSyncBehavior(std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyHostToHost, nullptr),
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemcpyAsync_Negative_Parameters") {
|
||||
using namespace std::placeholders;
|
||||
constexpr auto InvalidStream = [] {
|
||||
StreamGuard sg(Streams::created);
|
||||
return sg.stream();
|
||||
};
|
||||
|
||||
SECTION("Host to device") {
|
||||
LinearAllocGuard<int> device_alloc(LinearAllocs::hipMalloc, kPageSize);
|
||||
LinearAllocGuard<int> host_alloc(LinearAllocs::hipHostMalloc, kPageSize);
|
||||
|
||||
MemcpyCommonNegativeTests(std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyHostToDevice, nullptr),
|
||||
device_alloc.ptr(), host_alloc.ptr(), kPageSize);
|
||||
|
||||
SECTION("Invalid MemcpyKind") {
|
||||
HIP_CHECK_ERROR(hipMemcpyAsync(device_alloc.ptr(), host_alloc.ptr(), kPageSize,
|
||||
static_cast<hipMemcpyKind>(-1), nullptr),
|
||||
hipErrorInvalidMemcpyDirection);
|
||||
}
|
||||
|
||||
SECTION("Invalid stream") {
|
||||
HIP_CHECK_ERROR(hipMemcpyAsync(device_alloc.ptr(), host_alloc.ptr(), kPageSize,
|
||||
hipMemcpyHostToDevice, InvalidStream()),
|
||||
hipErrorContextIsDestroyed);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Device to host") {
|
||||
LinearAllocGuard<int> device_alloc(LinearAllocs::hipMalloc, kPageSize);
|
||||
LinearAllocGuard<int> host_alloc(LinearAllocs::hipHostMalloc, kPageSize);
|
||||
|
||||
MemcpyCommonNegativeTests(std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyDeviceToHost, nullptr),
|
||||
host_alloc.ptr(), device_alloc.ptr(), kPageSize);
|
||||
|
||||
SECTION("Invalid MemcpyKind") {
|
||||
HIP_CHECK_ERROR(hipMemcpyAsync(host_alloc.ptr(), device_alloc.ptr(), kPageSize,
|
||||
static_cast<hipMemcpyKind>(-1), nullptr),
|
||||
hipErrorInvalidMemcpyDirection);
|
||||
}
|
||||
|
||||
SECTION("Invalid stream") {
|
||||
HIP_CHECK_ERROR(hipMemcpyAsync(host_alloc.ptr(), device_alloc.ptr(), kPageSize,
|
||||
hipMemcpyDeviceToHost, InvalidStream()),
|
||||
hipErrorContextIsDestroyed);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Host to host") {
|
||||
LinearAllocGuard<int> src_alloc(LinearAllocs::hipHostMalloc, kPageSize);
|
||||
LinearAllocGuard<int> dst_alloc(LinearAllocs::hipHostMalloc, kPageSize);
|
||||
|
||||
MemcpyCommonNegativeTests(std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyHostToHost, nullptr),
|
||||
dst_alloc.ptr(), src_alloc.ptr(), kPageSize);
|
||||
|
||||
SECTION("Invalid MemcpyKind") {
|
||||
HIP_CHECK_ERROR(hipMemcpyAsync(dst_alloc.ptr(), src_alloc.ptr(), kPageSize,
|
||||
static_cast<hipMemcpyKind>(-1), nullptr),
|
||||
hipErrorInvalidMemcpyDirection);
|
||||
}
|
||||
|
||||
SECTION("Invalid stream") {
|
||||
HIP_CHECK_ERROR(hipMemcpyAsync(dst_alloc.ptr(), src_alloc.ptr(), kPageSize,
|
||||
hipMemcpyHostToHost, InvalidStream()),
|
||||
hipErrorContextIsDestroyed);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Device to device") {
|
||||
LinearAllocGuard<int> src_alloc(LinearAllocs::hipMalloc, kPageSize);
|
||||
LinearAllocGuard<int> dst_alloc(LinearAllocs::hipMalloc, kPageSize);
|
||||
|
||||
MemcpyCommonNegativeTests(
|
||||
std::bind(hipMemcpyAsync, _1, _2, _3, hipMemcpyDeviceToDevice, nullptr), dst_alloc.ptr(),
|
||||
src_alloc.ptr(), kPageSize);
|
||||
|
||||
SECTION("Invalid MemcpyKind") {
|
||||
HIP_CHECK_ERROR(hipMemcpyAsync(src_alloc.ptr(), dst_alloc.ptr(), kPageSize,
|
||||
static_cast<hipMemcpyKind>(-1), nullptr),
|
||||
hipErrorInvalidMemcpyDirection);
|
||||
}
|
||||
|
||||
SECTION("Invalid stream") {
|
||||
HIP_CHECK_ERROR(hipMemcpyAsync(dst_alloc.ptr(), src_alloc.ptr(), kPageSize,
|
||||
hipMemcpyDeviceToDevice, InvalidStream()),
|
||||
hipErrorContextIsDestroyed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
Copyright (c) 2022 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 <hip_test_common.hh>
|
||||
#include <hip/hip_runtime_api.h>
|
||||
#include <memcpy1d_tests_common.hh>
|
||||
#include <resource_guards.hh>
|
||||
#include <utils.hh>
|
||||
|
||||
static hipStream_t InvalidStream() {
|
||||
StreamGuard sg(Streams::created);
|
||||
return sg.stream();
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemcpyDtoHAsync_Positive_Basic") {
|
||||
const auto stream_type = GENERATE(Streams::nullstream, Streams::perThread, Streams::created);
|
||||
const StreamGuard stream_guard(stream_type);
|
||||
|
||||
const auto f = [stream = stream_guard.stream()](void* dst, void* src, size_t count) {
|
||||
return hipMemcpyDtoHAsync(dst, reinterpret_cast<hipDeviceptr_t>(src), count, stream);
|
||||
};
|
||||
MemcpyDeviceToHostShell<true>(f, stream_guard.stream());
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemcpyDtoHAsync_Positive_Synchronization_Behavior") {
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
SECTION("Device memory to pageable host memory") {
|
||||
MemcpyDtoHPageableSyncBehavior(
|
||||
[](void* dst, void* src, size_t count) {
|
||||
return hipMemcpyDtoHAsync(dst, reinterpret_cast<hipDeviceptr_t>(src), count, nullptr);
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
SECTION("Device memory to pinned host memory") {
|
||||
MemcpyDtoHPinnedSyncBehavior(
|
||||
[](void* dst, void* src, size_t count) {
|
||||
return hipMemcpyDtoHAsync(dst, reinterpret_cast<hipDeviceptr_t>(src), count, nullptr);
|
||||
},
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemcpyDtoHAsync_Negative_Parameters") {
|
||||
using namespace std::placeholders;
|
||||
LinearAllocGuard<int> device_alloc(LinearAllocs::hipMalloc, kPageSize);
|
||||
LinearAllocGuard<int> host_alloc(LinearAllocs::hipHostMalloc, kPageSize);
|
||||
|
||||
MemcpyCommonNegativeTests(
|
||||
[](void* dst, void* src, size_t count) {
|
||||
return hipMemcpyDtoHAsync(dst, reinterpret_cast<hipDeviceptr_t>(src), count, nullptr);
|
||||
},
|
||||
host_alloc.ptr(), device_alloc.ptr(), kPageSize);
|
||||
|
||||
SECTION("Invalid stream") {
|
||||
HIP_CHECK_ERROR(
|
||||
hipMemcpyDtoHAsync(host_alloc.ptr(), reinterpret_cast<hipDeviceptr_t>(device_alloc.ptr()),
|
||||
kPageSize, InvalidStream()),
|
||||
hipErrorContextIsDestroyed);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemcpyHtoDAsync_Positive_Basic") {
|
||||
const auto stream_type = GENERATE(Streams::nullstream, Streams::perThread, Streams::created);
|
||||
const StreamGuard stream_guard(stream_type);
|
||||
|
||||
const auto f = [stream = stream_guard.stream()](void* dst, void* src, size_t count) {
|
||||
return hipMemcpyHtoDAsync(reinterpret_cast<hipDeviceptr_t>(dst), src, count, stream);
|
||||
};
|
||||
MemcpyHostToDeviceShell<true>(f, stream_guard.stream());
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemcpyHtoDAsync_Positive_Synchronization_Behavior") {
|
||||
// This behavior differs on NVIDIA and AMD, on AMD the hipMemcpy calls is synchronous with
|
||||
// respect to the host
|
||||
#if HT_AMD
|
||||
HipTest::HIP_SKIP_TEST(
|
||||
"EXSWCPHIPT-127 - MemcpyAsync from host to device memory behavior differs on AMD and "
|
||||
"Nvidia");
|
||||
return;
|
||||
#endif
|
||||
MemcpyHtoDSyncBehavior(
|
||||
[](void* dst, void* src, size_t count) {
|
||||
return hipMemcpyHtoDAsync(reinterpret_cast<hipDeviceptr_t>(dst), src, count, nullptr);
|
||||
},
|
||||
false);
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemcpyHtoDAsync_Negative_Parameters") {
|
||||
using namespace std::placeholders;
|
||||
LinearAllocGuard<int> device_alloc(LinearAllocs::hipMalloc, kPageSize);
|
||||
LinearAllocGuard<int> host_alloc(LinearAllocs::hipHostMalloc, kPageSize);
|
||||
|
||||
MemcpyCommonNegativeTests(
|
||||
[](void* dst, void* src, size_t count) {
|
||||
return hipMemcpyHtoDAsync(reinterpret_cast<hipDeviceptr_t>(dst), src, count, nullptr);
|
||||
},
|
||||
device_alloc.ptr(), host_alloc.ptr(), kPageSize);
|
||||
|
||||
SECTION("Invalid stream") {
|
||||
HIP_CHECK_ERROR(hipMemcpyHtoDAsync(reinterpret_cast<hipDeviceptr_t>(device_alloc.ptr()),
|
||||
host_alloc.ptr(), kPageSize, InvalidStream()),
|
||||
hipErrorContextIsDestroyed);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemcpyDtoDAsync_Positive_Basic") {
|
||||
const auto stream_type = GENERATE(Streams::nullstream, Streams::perThread, Streams::created);
|
||||
const StreamGuard stream_guard(stream_type);
|
||||
|
||||
SECTION("Device to device") {
|
||||
SECTION("Peer access enabled") {
|
||||
MemcpyDeviceToDeviceShell<true, true>(
|
||||
[stream = stream_guard.stream()](void* dst, void* src, size_t count) {
|
||||
return hipMemcpyDtoDAsync(reinterpret_cast<hipDeviceptr_t>(dst),
|
||||
reinterpret_cast<hipDeviceptr_t>(src), count, stream);
|
||||
});
|
||||
}
|
||||
SECTION("Peer access disabled") {
|
||||
MemcpyDeviceToDeviceShell<true, false>(
|
||||
[stream = stream_guard.stream()](void* dst, void* src, size_t count) {
|
||||
return hipMemcpyDtoDAsync(reinterpret_cast<hipDeviceptr_t>(dst),
|
||||
reinterpret_cast<hipDeviceptr_t>(src), count, stream);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemcpyDtoDAsync_Positive_Synchronization_Behavior") {
|
||||
MemcpyDtoDSyncBehavior(
|
||||
[](void* dst, void* src, size_t count) {
|
||||
return hipMemcpyDtoDAsync(reinterpret_cast<hipDeviceptr_t>(dst),
|
||||
reinterpret_cast<hipDeviceptr_t>(src), count, nullptr);
|
||||
},
|
||||
false);
|
||||
}
|
||||
|
||||
TEST_CASE("Unit_hipMemcpyDtoDAsync_Negative_Parameters") {
|
||||
using namespace std::placeholders;
|
||||
LinearAllocGuard<int> src_alloc(LinearAllocs::hipMalloc, kPageSize);
|
||||
LinearAllocGuard<int> dst_alloc(LinearAllocs::hipMalloc, kPageSize);
|
||||
|
||||
MemcpyCommonNegativeTests(
|
||||
[](void* dst, void* src, size_t count) {
|
||||
return hipMemcpyDtoDAsync(reinterpret_cast<hipDeviceptr_t>(dst),
|
||||
reinterpret_cast<hipDeviceptr_t>(src), count, nullptr);
|
||||
},
|
||||
dst_alloc.ptr(), src_alloc.ptr(), kPageSize);
|
||||
|
||||
SECTION("Invalid stream") {
|
||||
HIP_CHECK_ERROR(hipMemcpyDtoDAsync(reinterpret_cast<hipDeviceptr_t>(dst_alloc.ptr()),
|
||||
reinterpret_cast<hipDeviceptr_t>(src_alloc.ptr()), kPageSize,
|
||||
InvalidStream()),
|
||||
hipErrorContextIsDestroyed);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,408 @@
|
||||
/*
|
||||
Copyright (c) 2022 - present 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
This testcase verifies the following scenarios
|
||||
1. hipMemcpyAsync with kernel launch
|
||||
2. H2D-D2D-D2H-H2PinnMem and device context change scenarios
|
||||
3. This test launches multiple threads which uses same stream to deploy kernel
|
||||
and also launch hipMemcpyAsync() api. This test case is simulate the scenario
|
||||
reported in SWDEV-181598.
|
||||
*/
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_kernels.hh>
|
||||
#include <hip_test_checkers.hh>
|
||||
#include <atomic>
|
||||
|
||||
#define NUM_THREADS 16
|
||||
|
||||
static constexpr auto NUM_ELM{1024 * 1024};
|
||||
|
||||
|
||||
|
||||
static constexpr size_t N_ELMTS{32 * 1024};
|
||||
std::atomic<size_t> Thread_count { 0 };
|
||||
static unsigned blocksPerCU{6}; // to hide latency
|
||||
static unsigned threadsPerBlock{256};
|
||||
|
||||
template<typename T>
|
||||
void Thread_func(T *A_d, T *B_d, T* C_d, T* C_h, size_t Nbytes,
|
||||
hipStream_t mystream) {
|
||||
unsigned blocks = HipTest::setNumBlocks(blocksPerCU,
|
||||
threadsPerBlock, N_ELMTS);
|
||||
hipLaunchKernelGGL(HipTest::vector_square, dim3(blocks),
|
||||
dim3(threadsPerBlock), 0,
|
||||
mystream, A_d, C_d, N_ELMTS);
|
||||
HIP_CHECK(hipGetLastError());
|
||||
HIP_CHECK(hipMemcpyAsync(C_h, C_d, Nbytes, hipMemcpyDeviceToHost, mystream));
|
||||
// The following two MemcpyAsync calls are for sole
|
||||
// purpose of loading stream with multiple async calls
|
||||
HIP_CHECK(hipMemcpyAsync(B_d, A_d, Nbytes,
|
||||
hipMemcpyDeviceToDevice, mystream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_d, A_d, Nbytes,
|
||||
hipMemcpyDeviceToDevice, mystream));
|
||||
Thread_count++;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Thread_func_MultiStream() {
|
||||
int Data_mismatch = 0;
|
||||
T *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr};
|
||||
T *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr};
|
||||
size_t Nbytes = N_ELMTS * sizeof(T);
|
||||
unsigned blocks = HipTest::setNumBlocks(blocksPerCU,
|
||||
threadsPerBlock, N_ELMTS);
|
||||
|
||||
HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N_ELMTS, false);
|
||||
hipStream_t mystream;
|
||||
HIP_CHECK(hipStreamCreateWithFlags(&mystream, hipStreamNonBlocking));
|
||||
HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice, mystream));
|
||||
hipLaunchKernelGGL((HipTest::vector_square), dim3(blocks),
|
||||
dim3(threadsPerBlock), 0,
|
||||
mystream, A_d, C_d, N_ELMTS);
|
||||
HIP_CHECK(hipGetLastError());
|
||||
HIP_CHECK(hipMemcpyAsync(C_h, C_d, Nbytes, hipMemcpyDeviceToHost, mystream));
|
||||
// The following hipMemcpyAsync() is called only to
|
||||
// load stream with multiple Async calls
|
||||
HIP_CHECK(hipMemcpyAsync(B_d, A_d, Nbytes,
|
||||
hipMemcpyDeviceToDevice, mystream));
|
||||
Thread_count++;
|
||||
|
||||
HIP_CHECK(hipStreamSynchronize(mystream));
|
||||
HIP_CHECK(hipStreamDestroy(mystream));
|
||||
// Verifying result of the kernel computation
|
||||
for (size_t i = 0; i < N_ELMTS; i++) {
|
||||
if (C_h[i] != A_h[i] * A_h[i]) {
|
||||
Data_mismatch++;
|
||||
}
|
||||
}
|
||||
// Releasing resources
|
||||
HipTest::freeArrays<T>(A_d, B_d, C_d, A_h, B_h, C_h, false);
|
||||
REQUIRE(Data_mismatch == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
This testcase verifies hipMemcpyAsync API
|
||||
Initializes device variables
|
||||
Launches kernel and performs the sum of device variables
|
||||
copies the result to host variable and validates the result.
|
||||
*/
|
||||
TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_KernelLaunch", "", int, float,
|
||||
double) {
|
||||
size_t Nbytes = NUM_ELM * sizeof(TestType);
|
||||
|
||||
TestType *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr};
|
||||
TestType *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr};
|
||||
HIP_CHECK(hipSetDevice(0));
|
||||
hipStream_t stream;
|
||||
HIP_CHECK(hipStreamCreate(&stream));
|
||||
|
||||
HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, NUM_ELM, false);
|
||||
|
||||
HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_d, B_h, Nbytes, hipMemcpyHostToDevice, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
|
||||
hipLaunchKernelGGL(HipTest::vectorADD, dim3(1), dim3(1), 0, 0,
|
||||
static_cast<const TestType*>(A_d),
|
||||
static_cast<const TestType*>(B_d), C_d, NUM_ELM);
|
||||
HIP_CHECK(hipGetLastError());
|
||||
HIP_CHECK(hipMemcpyAsync(C_h, C_d, Nbytes, hipMemcpyDeviceToHost, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
HIP_CHECK(hipStreamDestroy(stream));
|
||||
|
||||
HipTest::checkVectorADD(A_h, B_h, C_h, NUM_ELM);
|
||||
|
||||
HipTest::freeArrays<TestType>(A_d, B_d, C_d, A_h, B_h, C_h, false);
|
||||
}
|
||||
/*
|
||||
This testcase verifies the following scenarios
|
||||
1. H2H,H2PinMem and PinnedMem2Host
|
||||
2. H2D-D2D-D2H in same GPU
|
||||
3. Pinned Host Memory to device variables in same GPU
|
||||
4. Device context change
|
||||
5. H2D-D2D-D2H peer GPU
|
||||
*/
|
||||
TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_H2H-H2D-D2H-H2PinMem", "", char, int,
|
||||
float, double) {
|
||||
TestType *A_d{nullptr}, *B_d{nullptr};
|
||||
TestType *A_h{nullptr}, *B_h{nullptr};
|
||||
TestType *A_Ph{nullptr}, *B_Ph{nullptr};
|
||||
HIP_CHECK(hipSetDevice(0));
|
||||
hipStream_t stream;
|
||||
HIP_CHECK(hipStreamCreate(&stream));
|
||||
HipTest::initArrays<TestType>(&A_d, &B_d, nullptr,
|
||||
&A_h, &B_h, nullptr,
|
||||
NUM_ELM*sizeof(TestType));
|
||||
HipTest::initArrays<TestType>(nullptr, nullptr, nullptr,
|
||||
&A_Ph, &B_Ph, nullptr,
|
||||
NUM_ELM*sizeof(TestType), true);
|
||||
|
||||
SECTION("H2H, H2PinMem and PinMem2H") {
|
||||
HIP_CHECK(hipMemcpyAsync(B_h, A_h, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyHostToHost, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(A_Ph, B_h, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyHostToHost, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_Ph, A_Ph, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyHostToHost, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
HipTest::checkTest(A_h, B_Ph, NUM_ELM);
|
||||
}
|
||||
|
||||
SECTION("H2D-D2D-D2H-SameGPU") {
|
||||
HIP_CHECK(hipMemcpyAsync(A_d, A_h, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyHostToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_d, A_d, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyDeviceToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_h, B_d, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyDeviceToHost, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
HipTest::checkTest(A_h, B_h, NUM_ELM);
|
||||
}
|
||||
|
||||
SECTION("pH2D-D2D-D2pH-SameGPU") {
|
||||
HIP_CHECK(hipMemcpyAsync(A_d, A_Ph, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyHostToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_d, A_d, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyDeviceToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_Ph, B_d, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyDeviceToHost, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
HipTest::checkTest(A_Ph, B_Ph, NUM_ELM);
|
||||
}
|
||||
SECTION("H2D-D2D-D2H-DeviceContextChange") {
|
||||
int deviceCount = 0;
|
||||
HIP_CHECK(hipGetDeviceCount(&deviceCount));
|
||||
if (deviceCount < 2) {
|
||||
SUCCEED("deviceCount less then 2");
|
||||
} else {
|
||||
int canAccessPeer = 0;
|
||||
HIP_CHECK(hipDeviceCanAccessPeer(&canAccessPeer, 0, 1));
|
||||
if (canAccessPeer) {
|
||||
HIP_CHECK(hipSetDevice(1));
|
||||
HIP_CHECK(hipMemcpyAsync(A_d, A_h, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyHostToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_d, A_d, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyDeviceToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_h, B_d, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyDeviceToHost, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
HipTest::checkTest(A_h, B_h, NUM_ELM);
|
||||
|
||||
} else {
|
||||
SUCCEED("P2P capability is not present");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("H2D-D2D-D2H-PeerGPU") {
|
||||
int deviceCount = 0;
|
||||
HIP_CHECK(hipGetDeviceCount(&deviceCount));
|
||||
if (deviceCount < 2) {
|
||||
SUCCEED("deviceCount less then 2");
|
||||
} else {
|
||||
int canAccessPeer = 0;
|
||||
HIP_CHECK(hipDeviceCanAccessPeer(&canAccessPeer, 0, 1));
|
||||
if (canAccessPeer) {
|
||||
HIP_CHECK(hipSetDevice(1));
|
||||
TestType *C_d{nullptr};
|
||||
HipTest::initArrays<TestType>(nullptr, nullptr, &C_d,
|
||||
nullptr, nullptr, nullptr,
|
||||
NUM_ELM*sizeof(TestType));
|
||||
HIP_CHECK(hipMemcpyAsync(A_d, A_h, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyHostToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(C_d, A_d, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyDeviceToDevice, stream));
|
||||
HIP_CHECK(hipMemcpyAsync(B_h, C_d, NUM_ELM*sizeof(TestType),
|
||||
hipMemcpyDeviceToHost, stream));
|
||||
HIP_CHECK(hipStreamSynchronize(stream));
|
||||
HipTest::checkTest(A_h, B_h, NUM_ELM);
|
||||
HIP_CHECK(hipFree(C_d));
|
||||
|
||||
} else {
|
||||
SUCCEED("P2P capability is not present");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HIP_CHECK(hipStreamDestroy(stream));
|
||||
|
||||
HipTest::freeArrays<TestType>(A_d, B_d, nullptr, A_h, B_h, nullptr, false);
|
||||
HipTest::freeArrays<TestType>(nullptr, nullptr, nullptr, A_Ph,
|
||||
B_Ph, nullptr, true);
|
||||
}
|
||||
|
||||
// This test launches multiple threads which uses same stream to deploy kernel
|
||||
// and also launch hipMemcpyAsync() api. This test case is simulate the scenario
|
||||
// reported in SWDEV-181598
|
||||
|
||||
TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_hipMultiMemcpyMultiThread", "",
|
||||
int, float, double) {
|
||||
size_t Nbytes = N_ELMTS * sizeof(TestType);
|
||||
|
||||
int Data_mismatch = 0;
|
||||
hipStream_t mystream;
|
||||
TestType *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr};
|
||||
TestType *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr};
|
||||
|
||||
HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N_ELMTS, false);
|
||||
|
||||
HIP_CHECK(hipStreamCreateWithFlags(&mystream, hipStreamNonBlocking));
|
||||
HIP_CHECK(hipMemcpyAsync(A_d, A_h, Nbytes, hipMemcpyHostToDevice, mystream));
|
||||
|
||||
std::thread T[NUM_THREADS];
|
||||
for (int i = 0; i < NUM_THREADS; i++) {
|
||||
T[i] = std::thread(Thread_func<TestType>, A_d, B_d, C_d,
|
||||
C_h, Nbytes, mystream);
|
||||
}
|
||||
|
||||
// Wait until all the threads finish their execution
|
||||
for (int i = 0; i < NUM_THREADS; i++) {
|
||||
T[i].join();
|
||||
}
|
||||
|
||||
HIP_CHECK(hipStreamSynchronize(mystream));
|
||||
HIP_CHECK(hipStreamDestroy(mystream));
|
||||
|
||||
// Verifying the result of the kernel computation
|
||||
for (size_t i = 0; i < N_ELMTS; i++) {
|
||||
if (C_h[i] != A_h[i] * A_h[i]) {
|
||||
Data_mismatch++;
|
||||
}
|
||||
}
|
||||
REQUIRE(Thread_count.load() == NUM_THREADS);
|
||||
REQUIRE(Data_mismatch == 0);
|
||||
HipTest::freeArrays<TestType>(A_d, B_d, C_d, A_h, B_h, C_h, false);
|
||||
Thread_count.exchange(0);
|
||||
}
|
||||
|
||||
TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_hipMultiMemcpyMultiThreadMultiStream",
|
||||
"", int, float, double) {
|
||||
std::thread T[NUM_THREADS];
|
||||
for (int i = 0; i < NUM_THREADS; i++) {
|
||||
T[i] = std::thread(Thread_func_MultiStream<TestType>);
|
||||
}
|
||||
|
||||
// Wait until all the threads finish their execution
|
||||
for (int i = 0; i < NUM_THREADS; i++) {
|
||||
T[i].join();
|
||||
}
|
||||
|
||||
REQUIRE(Thread_count.load() == NUM_THREADS);
|
||||
Thread_count.exchange(0);
|
||||
}
|
||||
|
||||
/*
|
||||
This testcase verifies hipMemcpy API with pinnedMemory and hostRegister
|
||||
along with kernel launches
|
||||
*/
|
||||
|
||||
TEMPLATE_TEST_CASE("Unit_hipMemcpyAsync_PinnedRegMemWithKernelLaunch",
|
||||
"", int, float, double) {
|
||||
int numDevices = 0;
|
||||
HIP_CHECK(hipGetDeviceCount(&numDevices));
|
||||
if (numDevices < 2) {
|
||||
SUCCEED("No of devices are less than 2");
|
||||
} else {
|
||||
// 1 refers to pinned Memory
|
||||
// 2 refers to register Memory
|
||||
int MallocPinType = GENERATE(0, 1);
|
||||
size_t Nbytes = NUM_ELM * sizeof(TestType);
|
||||
unsigned blocks = HipTest::setNumBlocks(blocksPerCU,
|
||||
threadsPerBlock, NUM_ELM);
|
||||
|
||||
TestType *A_d{nullptr}, *B_d{nullptr}, *C_d{nullptr};
|
||||
TestType *X_d{nullptr}, *Y_d{nullptr}, *Z_d{nullptr};
|
||||
TestType *A_h{nullptr}, *B_h{nullptr}, *C_h{nullptr};
|
||||
if (MallocPinType) {
|
||||
HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, NUM_ELM, true);
|
||||
} else {
|
||||
A_h = reinterpret_cast<TestType*>(malloc(Nbytes));
|
||||
HIP_CHECK(hipHostRegister(A_h, Nbytes, hipHostRegisterDefault));
|
||||
B_h = reinterpret_cast<TestType*>(malloc(Nbytes));
|
||||
HIP_CHECK(hipHostRegister(B_h, Nbytes, hipHostRegisterDefault));
|
||||
C_h = reinterpret_cast<TestType*>(malloc(Nbytes));
|
||||
HIP_CHECK(hipHostRegister(C_h, Nbytes, hipHostRegisterDefault));
|
||||
HipTest::initArrays<TestType>(&A_d, &B_d, &C_d, nullptr, nullptr,
|
||||
nullptr, NUM_ELM, false);
|
||||
HipTest::setDefaultData<TestType>(NUM_ELM, A_h, B_h, C_h);
|
||||
}
|
||||
HIP_CHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
|
||||
HIP_CHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice));
|
||||
|
||||
hipLaunchKernelGGL(HipTest::vectorADD, dim3(blocks), dim3(threadsPerBlock),
|
||||
0, 0, static_cast<const TestType*>(A_d),
|
||||
static_cast<const TestType*>(B_d), C_d, NUM_ELM);
|
||||
HIP_CHECK(hipGetLastError());
|
||||
HIP_CHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
|
||||
HipTest::checkVectorADD(A_h, B_h, C_h, NUM_ELM);
|
||||
|
||||
unsigned int seed = time(0);
|
||||
HIP_CHECK(hipSetDevice(HipTest::RAND_R(&seed) % (numDevices-1)+1));
|
||||
|
||||
int device;
|
||||
HIP_CHECK(hipGetDevice(&device));
|
||||
INFO("hipMemcpy is set to happen between device 0 and device "
|
||||
<< device);
|
||||
HipTest::initArrays<TestType>(&X_d, &Y_d, &Z_d, nullptr,
|
||||
nullptr, nullptr, NUM_ELM, false);
|
||||
|
||||
hipStream_t gpu1Stream;
|
||||
HIP_CHECK(hipStreamCreate(&gpu1Stream));
|
||||
|
||||
for (int j = 0; j < NUM_ELM; j++) {
|
||||
A_h[j] = 0;
|
||||
B_h[j] = 0;
|
||||
C_h[j] = 0;
|
||||
}
|
||||
|
||||
HIP_CHECK(hipMemcpy(A_h, A_d, Nbytes, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipMemcpyAsync(X_d, A_h, Nbytes, hipMemcpyHostToDevice, gpu1Stream));
|
||||
HIP_CHECK(hipMemcpy(B_h, B_d, Nbytes, hipMemcpyDeviceToHost));
|
||||
HIP_CHECK(hipMemcpyAsync(Y_d, B_h, Nbytes, hipMemcpyHostToDevice, gpu1Stream));
|
||||
|
||||
hipLaunchKernelGGL(HipTest::vectorADD, dim3(blocks), dim3(threadsPerBlock),
|
||||
0, 0, static_cast<const TestType*>(X_d),
|
||||
static_cast<const TestType*>(Y_d), Z_d, NUM_ELM);
|
||||
HIP_CHECK(hipGetLastError());
|
||||
HIP_CHECK(hipMemcpyAsync(C_h, Z_d, Nbytes,
|
||||
hipMemcpyDeviceToHost, gpu1Stream));
|
||||
HIP_CHECK(hipStreamSynchronize(gpu1Stream));
|
||||
|
||||
HipTest::checkVectorADD(A_h, B_h, C_h, NUM_ELM);
|
||||
|
||||
if (MallocPinType) {
|
||||
HipTest::freeArrays<TestType>(A_d, B_d, C_d, A_h, B_h, C_h, true);
|
||||
} else {
|
||||
HIP_CHECK(hipHostUnregister(A_h));
|
||||
free(A_h);
|
||||
HIP_CHECK(hipHostUnregister(B_h));
|
||||
free(B_h);
|
||||
HIP_CHECK(hipHostUnregister(C_h));
|
||||
free(C_h);
|
||||
HipTest::freeArrays<TestType>(A_d, B_d, C_d, nullptr,
|
||||
nullptr, nullptr, false);
|
||||
}
|
||||
HipTest::freeArrays<TestType>(X_d, Y_d, Z_d, nullptr,
|
||||
nullptr, nullptr, false);
|
||||
HIP_CHECK(hipStreamDestroy(gpu1Stream));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,9 +316,8 @@ TEST_CASE("Unit_hipPointerGetAttribute_Negative") {
|
||||
== hipErrorInvalidValue);
|
||||
}
|
||||
SECTION("Pass invalid attribute") {
|
||||
hipPointer_attribute attr{HIP_POINTER_ATTRIBUTE_DEVICE_POINTER};
|
||||
REQUIRE(hipPointerGetAttribute(&data, attr,
|
||||
reinterpret_cast<hipDeviceptr_t>(A_h)) == hipErrorInvalidValue);
|
||||
REQUIRE(hipPointerGetAttribute(&data, static_cast<hipPointer_attribute>(-1),
|
||||
reinterpret_cast<hipDeviceptr_t>(A_h)) == hipErrorInvalidValue);
|
||||
}
|
||||
#if HT_AMD
|
||||
SECTION("Pass HIP_POINTER_ATTRIBUTE_IS_GPU_DIRECT_RDMA_CAPABLE"
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# Copyright (c) 2023 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.
|
||||
|
||||
# Common Tests - Test independent of all platforms
|
||||
if(HIP_PLATFORM MATCHES "amd")
|
||||
set(TEST_SRC
|
||||
hipExtModuleLaunchKernel.cc
|
||||
)
|
||||
|
||||
# Note to pass arch use format like -DOFFLOAD_ARCH_STR="--offload-arch=gfx900 --offload-arch=gfx906"
|
||||
# having space at the start/end of OFFLOAD_ARCH_STR can cause build failures
|
||||
|
||||
add_custom_target(copyKernel.code
|
||||
COMMAND ${CMAKE_CXX_COMPILER} -mcode-object-version=5 --genco ${OFFLOAD_ARCH_STR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/copyKernel.cc
|
||||
-o ${CMAKE_CURRENT_BINARY_DIR}/../../unit/module/copyKernel.code
|
||||
-I${CMAKE_CURRENT_SOURCE_DIR}/../../../../include/
|
||||
-I${CMAKE_CURRENT_SOURCE_DIR}/../../include --rocm-path=${ROCM_PATH})
|
||||
|
||||
add_custom_target(copyKernel.s
|
||||
COMMAND ${CMAKE_CXX_COMPILER} -mcode-object-version=5 -S ${CMAKE_CURRENT_SOURCE_DIR}/copyKernel.cc
|
||||
-o ${CMAKE_CURRENT_BINARY_DIR}/../../unit/module/copyKernel.s
|
||||
-I${CMAKE_CURRENT_SOURCE_DIR}/../../../../include/
|
||||
-I${CMAKE_CURRENT_SOURCE_DIR}/../../include --rocm-path=${ROCM_PATH})
|
||||
|
||||
hip_add_exe_to_target(NAME ModuleTest
|
||||
TEST_SRC ${TEST_SRC}
|
||||
TEST_TARGET_NAME build_tests COMMON_SHARED_SRC ${COMMON_SHARED_SRC})
|
||||
|
||||
add_dependencies(build_tests copyKernel.code copyKernel.s)
|
||||
endif()
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright (c) 2023 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 "hip/hip_runtime.h"
|
||||
|
||||
extern "C" __global__ void copy_ker(int* Ad, int *Bd, size_t size) {
|
||||
int myId = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if (myId < size) {
|
||||
Bd[myId] = Ad[myId];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
Copyright (c) 2023 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup hipExtModuleLaunchKernel hipExtModuleLaunchKernel
|
||||
* @{
|
||||
* @ingroup KernelTest
|
||||
* `hipError_t hipExtModuleLaunchKernel (hipFunction_t f,
|
||||
* uint32_t globalWorkSizeX,
|
||||
* uint32_t globalWorkSizeY,
|
||||
* uint32_t globalWorkSizeZ,
|
||||
* uint32_t localWorkSizeX,
|
||||
* uint32_t localWorkSizeY,
|
||||
* uint32_t localWorkSizeZ,
|
||||
* size_t sharedMemBytes,
|
||||
* hipStream_t hStream,
|
||||
* void ** kernelParams,
|
||||
* void ** extra,
|
||||
* hipEvent_t startEvent = nullptr,
|
||||
* hipEvent_t stopEvent = nullptr,
|
||||
* uint32_t flags = 0
|
||||
* )` -
|
||||
* Launches kernel with parameters and shared memory on stream with arguments
|
||||
* passed to kernel params or extra arguments.
|
||||
*/
|
||||
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip_test_defgroups.hh>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "hip/hip_ext.h"
|
||||
#include <regex> // NOLINT
|
||||
|
||||
static constexpr auto totalWorkGroups{1024};
|
||||
static constexpr auto localWorkSize{512};
|
||||
static constexpr auto lastWorkSizeEven{256};
|
||||
static constexpr auto lastWorkSizeOdd{257};
|
||||
|
||||
#define fileName "copyKernel.code"
|
||||
#define kernel_name "copy_ker"
|
||||
|
||||
/**
|
||||
Local Function to search a string in file.
|
||||
*/
|
||||
static bool searchRegExpr(const std::regex& expr, const char* filename) {
|
||||
std::ifstream assemblyfile(filename, std::ifstream::binary);
|
||||
REQUIRE(true == assemblyfile.is_open());
|
||||
|
||||
// Copy the contents of the file to buffer
|
||||
assemblyfile.seekg(0, assemblyfile.end);
|
||||
int len = assemblyfile.tellg();
|
||||
assemblyfile.seekg(0, assemblyfile.beg);
|
||||
char *fbuf = new char[len + 1];
|
||||
assemblyfile.read(fbuf, len);
|
||||
fbuf[len] = '\0';
|
||||
|
||||
// Search for uniform_work_group_size
|
||||
std::smatch pattern;
|
||||
std::string assemblyStr = fbuf;
|
||||
bool bfound = std::regex_search(assemblyStr, pattern, expr);
|
||||
delete[] fbuf;
|
||||
assemblyfile.close();
|
||||
return bfound;
|
||||
}
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Parse the Code Object Assembly file copyKernel.s and verify
|
||||
* if .uniform_work_group_size metadata is available.
|
||||
* ------------------------
|
||||
* - catch\unit\module\hipExtModuleLaunchKernel.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.7
|
||||
*/
|
||||
TEST_CASE("Unit_hipExtModuleLaunchKernel_CheckCodeObjAttr") {
|
||||
// Open copyKernel.s and read the file
|
||||
const std::regex regexp("uniform_work_group_size\\s*:\\s*[0-1]");
|
||||
REQUIRE(true == searchRegExpr(regexp, "copyKernel.s"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Precondition: .uniform_work_group_size = 1. Which means uniform workgroup
|
||||
* is enforced.
|
||||
* - Create a buffer of size globalWorkSizeX = (non multiple of localWorkSizeX)
|
||||
* and launch a kernel to perform some operations on it. If uniform work grouping
|
||||
* is enforced then hipExtModuleLaunchKernel returns hipErrorInvalidValue.
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch\unit\module\hipExtModuleLaunchKernel.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.7
|
||||
*/
|
||||
TEST_CASE("Unit_hipExtModuleLaunchKernel_NonUniformWorkGroup") {
|
||||
// first check if uniform_work_group_size = 1.
|
||||
const std::regex regexp("uniform_work_group_size\\s*:\\s*1");
|
||||
if (false == searchRegExpr(regexp, "copyKernel.s")) {
|
||||
HipTest::HIP_SKIP_TEST("uniform_work_group_size != 1. Skipping test ...");
|
||||
return;
|
||||
}
|
||||
REQUIRE(true == searchRegExpr(regexp, "copyKernel.s"));
|
||||
auto isEven = GENERATE(0, 1);
|
||||
// Calculate size
|
||||
auto lastWorkSize = isEven ? lastWorkSizeEven : lastWorkSizeOdd;
|
||||
size_t arraylength =
|
||||
(totalWorkGroups - 1)*localWorkSize + lastWorkSize;
|
||||
size_t sizeBytes{arraylength * sizeof(int)};
|
||||
// Get module and function from module
|
||||
hipModule_t Module;
|
||||
hipFunction_t Function;
|
||||
HIP_CHECK(hipModuleLoad(&Module, fileName));
|
||||
HIP_CHECK(hipModuleGetFunction(&Function, Module, kernel_name));
|
||||
// Allocate resources
|
||||
int *A = new int[arraylength];
|
||||
REQUIRE(A != nullptr);
|
||||
int *B = new int[arraylength];
|
||||
REQUIRE(B != nullptr);
|
||||
// Inititialize data
|
||||
for (size_t i = 0; i < arraylength; i++) {
|
||||
A[i] = i;
|
||||
}
|
||||
int *Ad, *Bd;
|
||||
HIP_CHECK(hipMalloc(&Ad, sizeBytes));
|
||||
HIP_CHECK(hipMalloc(&Bd, sizeBytes));
|
||||
struct {
|
||||
void* _Ad;
|
||||
void* _Bd;
|
||||
size_t buffersize;
|
||||
} args;
|
||||
|
||||
args._Ad = Ad;
|
||||
args._Bd = Bd;
|
||||
args.buffersize = arraylength;
|
||||
size_t size = sizeof(args);
|
||||
|
||||
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args,
|
||||
HIP_LAUNCH_PARAM_BUFFER_SIZE, &size,
|
||||
HIP_LAUNCH_PARAM_END};
|
||||
// Memcpy from A to Ad
|
||||
HIP_CHECK(hipMemcpy(Ad, A, sizeBytes, hipMemcpyDefault));
|
||||
REQUIRE(hipErrorInvalidValue == hipExtModuleLaunchKernel(Function,
|
||||
arraylength, 1, 1, localWorkSize, 1, 1, 0, 0, NULL,
|
||||
reinterpret_cast<void**>(&config), 0));
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
HIP_CHECK(hipFree(Ad));
|
||||
HIP_CHECK(hipFree(Bd));
|
||||
delete[] A;
|
||||
delete[] B;
|
||||
HIP_CHECK(hipModuleUnload(Module));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Description
|
||||
* ------------------------
|
||||
* - Create a buffer of size globalWorkSizeX = (multiple of localWorkSizeX)
|
||||
* and launch a kernel to perform some operations on it. Verify the output. This
|
||||
* operation should be allowed for both uniform_work_group_size = true/false.
|
||||
*
|
||||
* Test source
|
||||
* ------------------------
|
||||
* - catch\unit\module\hipExtModuleLaunchKernel.cc
|
||||
* Test requirements
|
||||
* ------------------------
|
||||
* - HIP_VERSION >= 5.7
|
||||
*/
|
||||
TEST_CASE("Unit_hipExtModuleLaunchKernel_UniformWorkGroup") {
|
||||
size_t arraylength = totalWorkGroups * localWorkSize;
|
||||
size_t sizeBytes{arraylength * sizeof(int)};
|
||||
// Get module and function from module
|
||||
hipModule_t Module;
|
||||
hipFunction_t Function;
|
||||
HIP_CHECK(hipModuleLoad(&Module, fileName));
|
||||
HIP_CHECK(hipModuleGetFunction(&Function, Module, kernel_name));
|
||||
// Allocate resources
|
||||
int *A = new int[arraylength];
|
||||
REQUIRE(A != nullptr);
|
||||
int *B = new int[arraylength];
|
||||
REQUIRE(B != nullptr);
|
||||
// Inititialize data
|
||||
for (size_t i = 0; i < arraylength; i++) {
|
||||
A[i] = i;
|
||||
}
|
||||
int *Ad, *Bd;
|
||||
HIP_CHECK(hipMalloc(&Ad, sizeBytes));
|
||||
HIP_CHECK(hipMalloc(&Bd, sizeBytes));
|
||||
struct {
|
||||
void* _Ad;
|
||||
void* _Bd;
|
||||
size_t buffersize;
|
||||
} args;
|
||||
|
||||
args._Ad = Ad;
|
||||
args._Bd = Bd;
|
||||
args.buffersize = arraylength;
|
||||
size_t size = sizeof(args);
|
||||
|
||||
void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args,
|
||||
HIP_LAUNCH_PARAM_BUFFER_SIZE, &size,
|
||||
HIP_LAUNCH_PARAM_END};
|
||||
// Memcpy from A to Ad
|
||||
HIP_CHECK(hipMemcpy(Ad, A, sizeBytes, hipMemcpyDefault));
|
||||
HIP_CHECK(hipExtModuleLaunchKernel(Function, arraylength, 1, 1,
|
||||
localWorkSize, 1, 1, 0, 0, NULL,
|
||||
reinterpret_cast<void**>(&config), 0));
|
||||
// Memcpy results back to host
|
||||
HIP_CHECK(hipMemcpy(B, Bd, sizeBytes, hipMemcpyDefault));
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
// Verify results
|
||||
for (size_t i = 0; i < arraylength; i++) {
|
||||
REQUIRE(B[i] == i);
|
||||
}
|
||||
HIP_CHECK(hipFree(Ad));
|
||||
HIP_CHECK(hipFree(Bd));
|
||||
delete[] A;
|
||||
delete[] B;
|
||||
HIP_CHECK(hipModuleUnload(Module));
|
||||
}
|
||||
@@ -24,6 +24,8 @@ THE SOFTWARE.
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
|
||||
VkFence VulkanTest::CreateFence() {
|
||||
VkFence fence;
|
||||
VkFenceCreateInfo fence_create_info = {};
|
||||
@@ -80,7 +82,7 @@ hipExternalMemoryHandleDesc VulkanTest::BuildMemoryDescriptor(VkDeviceMemory vk_
|
||||
hipExternalMemoryHandleDesc mem_handle_desc = {};
|
||||
mem_handle_desc.type = VulkanMemHandleTypeToHIPHandleType();
|
||||
#ifdef _WIN64
|
||||
mem_handle_desc.handle.win32.handle = GetMemoryHandle(ck_mem);
|
||||
mem_handle_desc.handle.win32.handle = GetMemoryHandle(vk_mem);
|
||||
#else
|
||||
mem_handle_desc.handle.fd = GetMemoryHandle(vk_mem);
|
||||
#endif
|
||||
@@ -170,7 +172,7 @@ bool VulkanTest::CheckExtensionSupport(std::vector<const char*> expected_extensi
|
||||
std::back_inserter(supported_extensions),
|
||||
[](const auto& p) { return p.extensionName; });
|
||||
|
||||
constexpr auto p = [](const char* l, const char* r) { return strcmp(l, r) < 0; };
|
||||
auto p = [](const char* l, const char* r) { return strcmp(l, r) < 0; };
|
||||
std::sort(expected_extensions.begin(), expected_extensions.end(), p);
|
||||
std::sort(supported_extensions.begin(), supported_extensions.end(), p);
|
||||
|
||||
@@ -328,7 +330,7 @@ int VulkanTest::GetSemaphoreHandle(VkSemaphore semaphore) {
|
||||
#ifdef _WIN64
|
||||
HANDLE
|
||||
VulkanTest::GetMemoryHandle(VkDeviceMemory memory) {
|
||||
Handle handle = 0;
|
||||
HANDLE handle = 0;
|
||||
|
||||
VkMemoryGetWin32HandleInfoKHR vkMemoryGetWin32HandleInfoKHR = {};
|
||||
vkMemoryGetWin32HandleInfoKHR.sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR;
|
||||
@@ -336,7 +338,7 @@ VulkanTest::GetMemoryHandle(VkDeviceMemory memory) {
|
||||
vkMemoryGetWin32HandleInfoKHR.handleType = _mem_handle_type;
|
||||
|
||||
PFN_vkGetMemoryWin32HandleKHR fpGetMemoryWin32HandleKHR =
|
||||
(PFN_vkGetMemoryWin32HandleKHR)vkGetDeviceProcAddr(m_device, "vkGetMemoryWin32HandleKHR");
|
||||
(PFN_vkGetMemoryWin32HandleKHR)vkGetDeviceProcAddr(_device, "vkGetMemoryWin32HandleKHR");
|
||||
|
||||
if (!fpGetMemoryWin32HandleKHR) {
|
||||
throw std::runtime_error("Failed to retrieve vkGetMemoryWin32HandleKHR");
|
||||
@@ -407,4 +409,5 @@ hipExternalSemaphore_t ImportBinarySemaphore(VulkanTest& vkt) {
|
||||
HIP_CHECK(hipImportExternalSemaphore(&hip_ext_semaphore, &sem_handle_desc));
|
||||
|
||||
return hip_ext_semaphore;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,12 +20,23 @@ THE SOFTWARE.
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _WIN64
|
||||
|
||||
#include <Windows.h>
|
||||
#include <winnt.h>
|
||||
#include <VersionHelpers.h>
|
||||
|
||||
#include <winapifamily.h>
|
||||
#include <dxgi1_2.h>
|
||||
#include <windef.h>
|
||||
#include <aclapi.h>
|
||||
#include <securitybaseapi.h>
|
||||
#include <vulkan/vulkan_win32.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <hip_test_common.hh>
|
||||
#include <hip/hip_runtime_api.h>
|
||||
|
||||
@@ -39,6 +50,72 @@ THE SOFTWARE.
|
||||
} \
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
class WindowsSecurityAttributes
|
||||
{
|
||||
protected:
|
||||
SECURITY_ATTRIBUTES m_winSecurityAttributes;
|
||||
PSECURITY_DESCRIPTOR m_winPSecurityDescriptor;
|
||||
|
||||
public:
|
||||
WindowsSecurityAttributes::WindowsSecurityAttributes()
|
||||
{
|
||||
m_winPSecurityDescriptor = (PSECURITY_DESCRIPTOR)calloc(1, SECURITY_DESCRIPTOR_MIN_LENGTH + 2 * sizeof(void **));
|
||||
if (!m_winPSecurityDescriptor) {
|
||||
throw std::runtime_error("Failed to allocate memory for security descriptor");
|
||||
}
|
||||
|
||||
PSID *ppSID = (PSID *)((PBYTE)m_winPSecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH);
|
||||
PACL *ppACL = (PACL *)((PBYTE)ppSID + sizeof(PSID *));
|
||||
|
||||
InitializeSecurityDescriptor(m_winPSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
|
||||
|
||||
SID_IDENTIFIER_AUTHORITY sidIdentifierAuthority = SECURITY_WORLD_SID_AUTHORITY;
|
||||
AllocateAndInitializeSid(&sidIdentifierAuthority, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, ppSID);
|
||||
|
||||
EXPLICIT_ACCESS explicitAccess;
|
||||
ZeroMemory(&explicitAccess, sizeof(EXPLICIT_ACCESS));
|
||||
explicitAccess.grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
|
||||
explicitAccess.grfAccessMode = SET_ACCESS;
|
||||
explicitAccess.grfInheritance = INHERIT_ONLY;
|
||||
explicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||||
explicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
|
||||
explicitAccess.Trustee.ptstrName = (LPTSTR) * ppSID;
|
||||
|
||||
SetEntriesInAcl(1, &explicitAccess, NULL, ppACL);
|
||||
|
||||
SetSecurityDescriptorDacl(m_winPSecurityDescriptor, TRUE, *ppACL, FALSE);
|
||||
|
||||
m_winSecurityAttributes.nLength = sizeof(m_winSecurityAttributes);
|
||||
m_winSecurityAttributes.lpSecurityDescriptor = m_winPSecurityDescriptor;
|
||||
m_winSecurityAttributes.bInheritHandle = TRUE;
|
||||
}
|
||||
|
||||
SECURITY_ATTRIBUTES *
|
||||
WindowsSecurityAttributes::operator&()
|
||||
{
|
||||
return &m_winSecurityAttributes;
|
||||
}
|
||||
|
||||
WindowsSecurityAttributes::~WindowsSecurityAttributes()
|
||||
{
|
||||
PSID *ppSID = (PSID *)((PBYTE)m_winPSecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH);
|
||||
PACL *ppACL = (PACL *)((PBYTE)ppSID + sizeof(PSID *));
|
||||
|
||||
if (*ppSID) {
|
||||
FreeSid(*ppSID);
|
||||
}
|
||||
if (*ppACL) {
|
||||
LocalFree(*ppACL);
|
||||
}
|
||||
free(m_winPSecurityDescriptor);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif /* _WIN64 */
|
||||
|
||||
|
||||
class VulkanTest {
|
||||
public:
|
||||
VulkanTest(bool enable_validation)
|
||||
@@ -256,4 +333,4 @@ VulkanTest::MappedBuffer<T> VulkanTest::CreateMappedStorage(uint32_t count,
|
||||
// Sometimes in CUDA the stream is not immediately ready after a semaphore has been signaled
|
||||
void PollStream(hipStream_t stream, hipError_t expected, uint32_t num_iterations = 5);
|
||||
|
||||
hipExternalSemaphore_t ImportBinarySemaphore(VulkanTest& vkt);
|
||||
hipExternalSemaphore_t ImportBinarySemaphore(VulkanTest& vkt);
|
||||
|
||||
@@ -21,76 +21,66 @@ THE SOFTWARE.
|
||||
*/
|
||||
#include "hip/hip_runtime.h"
|
||||
|
||||
texture<char, hipTextureType2D, hipReadModeElementType> texChar;
|
||||
texture<short, hipTextureType2D, hipReadModeElementType> texShort;
|
||||
texture<int, hipTextureType2D, hipReadModeElementType> texInt;
|
||||
texture<float, hipTextureType2D, hipReadModeElementType> texFloat;
|
||||
|
||||
texture<char4, hipTextureType2D, hipReadModeElementType> texChar4;
|
||||
texture<short4, hipTextureType2D, hipReadModeElementType> texShort4;
|
||||
texture<int4, hipTextureType2D, hipReadModeElementType> texInt4;
|
||||
texture<float4, hipTextureType2D, hipReadModeElementType> texFloat4;
|
||||
|
||||
extern "C" __global__ void tex2dKernelChar(char* outputData, int width, int height) {
|
||||
extern "C" __global__ void tex2dKernelChar(char* outputData,hipTextureObject_t texObj, int width, int height) {
|
||||
#if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
outputData[y * width + x] = tex2D(texChar, x, y);
|
||||
outputData[y * width + x] = tex2D<char>(texObj, x, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" __global__ void tex2dKernelShort(short* outputData, int width, int height) {
|
||||
extern "C" __global__ void tex2dKernelShort(short* outputData,hipTextureObject_t texObj, int width, int height) {
|
||||
#if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
outputData[y * width + x] = tex2D(texShort, x, y);
|
||||
outputData[y * width + x] = tex2D<short>(texObj, x, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" __global__ void tex2dKernelInt(int* outputData, int width, int height) {
|
||||
extern "C" __global__ void tex2dKernelInt(int* outputData,hipTextureObject_t texObj ,int width, int height) {
|
||||
#if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
outputData[y * width + x] = tex2D(texInt, x, y);
|
||||
outputData[y * width + x] = tex2D<int>(texObj, x, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" __global__ void tex2dKernelFloat(float* outputData, int width, int height) {
|
||||
extern "C" __global__ void tex2dKernelFloat(float* outputData,hipTextureObject_t texObj, int width, int height) {
|
||||
#if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
outputData[y * width + x] = tex2D(texFloat, x, y);
|
||||
outputData[y * width + x] = tex2D<float>(texObj, x, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" __global__ void tex2dKernelChar4(char4* outputData, int width, int height) {
|
||||
extern "C" __global__ void tex2dKernelChar4(char4* outputData,hipTextureObject_t texObj, int width, int height) {
|
||||
#if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
outputData[y * width + x] = tex2D(texChar4, x, y);
|
||||
outputData[y * width + x] = tex2D<char4>(texObj, x, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" __global__ void tex2dKernelShort4(short4* outputData, int width, int height) {
|
||||
extern "C" __global__ void tex2dKernelShort4(short4* outputData,hipTextureObject_t texObj, int width, int height) {
|
||||
#if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
outputData[y * width + x] = tex2D(texShort4, x, y);
|
||||
outputData[y * width + x] = tex2D<short4>(texObj, x, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" __global__ void tex2dKernelInt4(int4* outputData, int width, int height) {
|
||||
extern "C" __global__ void tex2dKernelInt4(int4* outputData,hipTextureObject_t texObj, int width, int height) {
|
||||
#if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
outputData[y * width + x] = tex2D(texInt4, x, y);
|
||||
outputData[y * width + x] = tex2D<int4>(texObj, x, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" __global__ void tex2dKernelFloat4(float4* outputData, int width, int height) {
|
||||
extern "C" __global__ void tex2dKernelFloat4(float4* outputData,hipTextureObject_t texObj, int width, int height) {
|
||||
#if !defined(__HIP_NO_IMAGE_SUPPORT) || !__HIP_NO_IMAGE_SUPPORT
|
||||
int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
outputData[y * width + x] = tex2D(texFloat4, x, y);
|
||||
outputData[y * width + x] = tex2D<float4>(texObj, x, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -65,6 +65,19 @@ static inline constexpr int rank() {
|
||||
return sizeof(T) / sizeof(decltype(T::x));
|
||||
}
|
||||
|
||||
#ifdef __HIP_PLATFORM_NVIDIA__
|
||||
template <typename T,
|
||||
typename std::enable_if<std::is_same<T, int4>::value ||
|
||||
std::is_same<T, short4>::value ||
|
||||
std::is_same<T, char4>::value ||
|
||||
std::is_same<T, float4>::value>::type *t = nullptr>
|
||||
static inline bool operator!=(const T& a, const T& b)
|
||||
{
|
||||
return (a.x != b.x) || (a.y != b.y) || (a.z != b.z) || (a.w != b.w);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
template<typename T>
|
||||
static inline T getRandom() {
|
||||
double r = 0;
|
||||
@@ -139,43 +152,42 @@ bool runTest(hipModule_t &module, const char *refName, const char *funcName) {
|
||||
}
|
||||
}
|
||||
|
||||
hipArray *array;
|
||||
HIP_ARRAY_DESCRIPTOR desc;
|
||||
desc.Format = format;
|
||||
desc.NumChannels = channels;
|
||||
desc.Width = width;
|
||||
desc.Height = height;
|
||||
HIP_CHECK(hipArrayCreate(&array, &desc));
|
||||
hipChannelFormatDesc channelDesc = hipCreateChannelDesc<T>();
|
||||
hipArray_t array;
|
||||
HIP_CHECK(hipMallocArray(&array, &channelDesc, width, height));
|
||||
|
||||
hip_Memcpy2D copyParam;
|
||||
memset(©Param, 0, sizeof(copyParam));
|
||||
copyParam.dstMemoryType = hipMemoryTypeArray;
|
||||
copyParam.dstArray = array;
|
||||
copyParam.srcMemoryType = hipMemoryTypeHost;
|
||||
copyParam.srcHost = hData;
|
||||
copyParam.srcPitch = width * sizeof(T);
|
||||
copyParam.WidthInBytes = copyParam.srcPitch;
|
||||
copyParam.Height = height;
|
||||
HIP_CHECK(hipMemcpyParam2D(©Param));
|
||||
const size_t spitch = width * sizeof(T);
|
||||
|
||||
textureReference *texref;
|
||||
HIP_CHECK(hipModuleGetTexRef(&texref, module, refName));
|
||||
HIP_CHECK(hipTexRefSetAddressMode(texref, 0, hipAddressModeClamp));
|
||||
HIP_CHECK(hipTexRefSetAddressMode(texref, 1, hipAddressModeClamp));
|
||||
HIP_CHECK(hipTexRefSetFilterMode(texref, hipFilterModePoint));
|
||||
HIP_CHECK(hipTexRefSetFlags(texref, HIP_TRSF_READ_AS_INTEGER));
|
||||
HIP_CHECK(hipTexRefSetFormat(texref, format, channels));
|
||||
HIP_CHECK(hipTexRefSetArray(texref, array, HIP_TRSA_OVERRIDE_FORMAT));
|
||||
HIP_CHECK(hipMemcpy2DToArray(array, 0, 0, hData, spitch, width * sizeof(T),
|
||||
height, hipMemcpyHostToDevice));
|
||||
|
||||
hipResourceDesc resDesc;
|
||||
memset(&resDesc, 0, sizeof(resDesc));
|
||||
resDesc.resType = hipResourceTypeArray;
|
||||
resDesc.res.array.array = array;
|
||||
|
||||
hipTextureDesc texDesc;
|
||||
memset(&texDesc, 0, sizeof(texDesc));
|
||||
texDesc.addressMode[0] = hipAddressModeClamp;
|
||||
texDesc.addressMode[1] = hipAddressModeClamp;
|
||||
texDesc.filterMode = hipFilterModePoint;
|
||||
texDesc.readMode = hipReadModeElementType;
|
||||
texDesc.normalizedCoords = 0;
|
||||
|
||||
hipTextureObject_t texObj;
|
||||
HIP_CHECK(hipCreateTextureObject(&texObj, &resDesc, &texDesc, nullptr));
|
||||
|
||||
T *dData = NULL;
|
||||
HIP_CHECK(hipMalloc((void** )&dData, size));
|
||||
|
||||
struct {
|
||||
void *_Ad;
|
||||
hipTextureObject_t _texObj;
|
||||
unsigned int _Bd;
|
||||
unsigned int _Cd;
|
||||
} args;
|
||||
args._Ad = (void*) dData;
|
||||
args._texObj = texObj;
|
||||
args._Bd = width;
|
||||
args._Cd = height;
|
||||
|
||||
@@ -192,7 +204,7 @@ bool runTest(hipModule_t &module, const char *refName, const char *funcName) {
|
||||
HIP_CHECK(
|
||||
hipModuleLaunchKernel(Function, 16, 16, 1, temp1, temp2, 1, 0, 0, NULL,
|
||||
(void** )&config));
|
||||
hipDeviceSynchronize();
|
||||
HIP_CHECK(hipDeviceSynchronize());
|
||||
|
||||
T *hOutputData = (T*) malloc(size);
|
||||
memset(hOutputData, 0, size);
|
||||
@@ -207,7 +219,7 @@ bool runTest(hipModule_t &module, const char *refName, const char *funcName) {
|
||||
}
|
||||
}
|
||||
}
|
||||
HIP_CHECK(hipUnbindTexture(texref));
|
||||
HIP_CHECK(hipDestroyTextureObject(texObj));
|
||||
HIP_CHECK(hipFree(dData));
|
||||
HIP_CHECK(hipFreeArray(array));
|
||||
free(hOutputData);
|
||||
@@ -230,7 +242,8 @@ int main(int argc, char** argv) {
|
||||
printf("Texture is not support on the device. Skipped.\n");
|
||||
return 0;
|
||||
}
|
||||
hipInit(0);
|
||||
HIP_CHECK(hipInit(0));
|
||||
HIP_CHECK(hipSetDevice(0));
|
||||
hipModule_t module;
|
||||
HIP_CHECK(hipModuleLoad(&module, fileName));
|
||||
testResult = testResult && runTest<char>(module, "texChar", "tex2dKernelChar");
|
||||
|
||||
+8
-1
@@ -23,8 +23,15 @@
|
||||
#include <hip/hip_runtime.h>
|
||||
#include <hip/hip_runtime_api.h>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
#define HIP_ASSERT(status) assert(status == hipSuccess)
|
||||
#define HIP_ASSERT(status) \
|
||||
{ \
|
||||
if ((status != hipSuccess)) { \
|
||||
std::cerr << "Failed in: " << __LINE__ << " on hip call: " #status << std::endl; \
|
||||
throw std::runtime_error("generic failure"); \
|
||||
} \
|
||||
}
|
||||
#define LEN 512
|
||||
|
||||
extern __device__ int square_me(int);
|
||||
|
||||
@@ -30,9 +30,9 @@ all: ${SRC}
|
||||
${CC} ${CPPFLAGS} $^ -o ${OBJ}
|
||||
|
||||
clean:
|
||||
rm ${OBJ}
|
||||
rm *.xml
|
||||
rm -r ./coverageReportHTML/testModules
|
||||
rm -r ./coverageReportHTML/testAPIs
|
||||
rm ./coverageReportHTML/*.html
|
||||
rm -f ${OBJ}
|
||||
rm -f *.xml
|
||||
rm -fr ./coverageReportHTML/testModules
|
||||
rm -fr ./coverageReportHTML/testAPIs
|
||||
rm -f ./coverageReportHTML/*.html
|
||||
.PHONY : clean
|
||||
|
||||
@@ -169,6 +169,18 @@ td.coverBarOutline
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
/* Directory view/File view (all): line count entry for files with
|
||||
deprecated functions */
|
||||
td.coverDeprecated
|
||||
{
|
||||
text-align: center;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
background-color: #d2d2d2;
|
||||
white-space: nowrap;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
/* Directory view/File view (all): line count entry for files with
|
||||
high coverage rate */
|
||||
td.coverNumHi
|
||||
|
||||
@@ -0,0 +1,733 @@
|
||||
Atomics [
|
||||
atomicCAS
|
||||
atomicCAS_system
|
||||
atomicAdd
|
||||
atomicAdd_system
|
||||
unsafeAtomicAdd
|
||||
safeAtomicAdd
|
||||
atomicSub
|
||||
atomicSub_system
|
||||
atomicExch
|
||||
atomicExch_system
|
||||
atomicMin
|
||||
atomicMin_system
|
||||
unsafeAtomicMin
|
||||
safeAtomicMin
|
||||
atomicMax
|
||||
atomicMax_system
|
||||
unsafeAtomicMax
|
||||
safeAtomicMax
|
||||
atomicInc
|
||||
atomicDec
|
||||
atomicAnd
|
||||
atomicAnd_system
|
||||
atomicOr
|
||||
atomicOr_system
|
||||
atomicXor
|
||||
atomicXor_system
|
||||
]
|
||||
|
||||
Builtin atomics [
|
||||
__hip_atomic_load
|
||||
__hip_atomic_store
|
||||
__hip_atomic_compare_exchange_weak
|
||||
__hip_atomic_compare_exchange_strong
|
||||
__hip_atomic_exchange
|
||||
__hip_atomic_fetch_add
|
||||
__hip_atomic_fetch_and
|
||||
__hip_atomic_fetch_or
|
||||
__hip_atomic_fetch_xor
|
||||
__hip_atomic_fetch_min
|
||||
__hip_atomic_fetch_max
|
||||
]
|
||||
|
||||
Cooperative groups [
|
||||
File restriction: cooperative_groups
|
||||
Device groups: (
|
||||
coalesced_group_tile
|
||||
coalesced_group
|
||||
grid_group
|
||||
multi_grid_group
|
||||
thread_block_tile
|
||||
thread_block
|
||||
)
|
||||
size
|
||||
thread_rank
|
||||
group_index
|
||||
thread_index
|
||||
shfl
|
||||
shfl_up
|
||||
shfl_down
|
||||
shfl_xor
|
||||
sync
|
||||
]
|
||||
|
||||
Warp [
|
||||
File restriction: cooperative_groups
|
||||
Device groups: (
|
||||
ballot
|
||||
any
|
||||
all
|
||||
shfl_down
|
||||
shfl_up
|
||||
shfl
|
||||
shfl_xor
|
||||
)
|
||||
__ballot
|
||||
__any
|
||||
__all
|
||||
__shfl_down
|
||||
__shfl_up
|
||||
__shfl
|
||||
__shfl_xor
|
||||
]
|
||||
|
||||
Launch bounds [
|
||||
Device groups: (
|
||||
launch_bounds
|
||||
)
|
||||
__launch_bounds__
|
||||
]
|
||||
|
||||
Channel descriptor [
|
||||
hipCreateChannelDesc
|
||||
hipCreateChannelDescHalf
|
||||
hipCreateChannelDescHalf1
|
||||
hipCreateChannelDescHalf2
|
||||
]
|
||||
|
||||
Device assert [
|
||||
assert
|
||||
static_assert
|
||||
]
|
||||
|
||||
Device clock [
|
||||
Device groups: (
|
||||
clock
|
||||
)
|
||||
clock
|
||||
clock64
|
||||
wall_clock64
|
||||
]
|
||||
|
||||
Device printf [
|
||||
printf
|
||||
]
|
||||
|
||||
HIP specific [
|
||||
Device groups: (
|
||||
hip_hc_8pk
|
||||
)
|
||||
__hip_hc_add8pk
|
||||
__hip_hc_sub8pk
|
||||
__hip_hc_mul8pk
|
||||
]
|
||||
|
||||
Device synchronization [
|
||||
__syncthreads
|
||||
__syncthreads_and
|
||||
__syncthreads_count
|
||||
__syncthreads_or
|
||||
]
|
||||
|
||||
Memory fence [
|
||||
__threadfence
|
||||
__threadfence_block
|
||||
__threadfence_system
|
||||
]
|
||||
|
||||
Device memory [
|
||||
memcpy
|
||||
memset
|
||||
]
|
||||
|
||||
Device math [
|
||||
rsqrt
|
||||
sqrt
|
||||
cbrt
|
||||
rcbrt
|
||||
hypot
|
||||
rhypot
|
||||
norm3d
|
||||
rnorm3d
|
||||
norm4d
|
||||
rnorm4d
|
||||
norm
|
||||
rnorm
|
||||
rsqrtf
|
||||
sqrtf
|
||||
cbrtf
|
||||
rcbrtf
|
||||
hypotf
|
||||
rhypotf
|
||||
norm3df
|
||||
rnorm3df
|
||||
norm4df
|
||||
rnorm4df
|
||||
normf
|
||||
rnormf
|
||||
rsqrt
|
||||
sqrt
|
||||
cbrt
|
||||
rcbrt
|
||||
hypot
|
||||
rhypot
|
||||
norm3d
|
||||
rnorm3d
|
||||
norm4d
|
||||
rnorm4d
|
||||
norm
|
||||
rnorm
|
||||
expf
|
||||
exp2f
|
||||
exp10f
|
||||
expm1f
|
||||
frexpf
|
||||
ldexpf
|
||||
powf
|
||||
powif
|
||||
scalbnf
|
||||
scalblnf
|
||||
log
|
||||
log2
|
||||
log10
|
||||
log1p
|
||||
logb
|
||||
ilogb
|
||||
logf
|
||||
log2f
|
||||
log10f
|
||||
log1pf
|
||||
logbf
|
||||
ilogbf
|
||||
sin
|
||||
cos
|
||||
tan
|
||||
sincos
|
||||
sinpi
|
||||
cospi
|
||||
sincospi
|
||||
asin
|
||||
acos
|
||||
atan
|
||||
atan2
|
||||
sinh
|
||||
cosh
|
||||
tanh
|
||||
asinh
|
||||
acosh
|
||||
atanh
|
||||
sinf
|
||||
cosf
|
||||
tanf
|
||||
sincosf
|
||||
sinpif
|
||||
cospif
|
||||
sincospif
|
||||
asinf
|
||||
acosf
|
||||
atanf
|
||||
atan2f
|
||||
sinhf
|
||||
coshf
|
||||
tanhf
|
||||
asinhf
|
||||
acoshf
|
||||
atanhf
|
||||
erf
|
||||
erfc
|
||||
erfinv
|
||||
erfcinv
|
||||
erfcx
|
||||
normcdf
|
||||
normcdfinv
|
||||
lgamma
|
||||
tgamma
|
||||
j0
|
||||
j1
|
||||
jn
|
||||
y0
|
||||
y1
|
||||
yn
|
||||
cyl_bessel_i0
|
||||
cyl_bessel_i1
|
||||
erff
|
||||
erfcf
|
||||
erfinvf
|
||||
erfcinvf
|
||||
erfcxf
|
||||
normcdff
|
||||
normcdfinvf
|
||||
lgammaf
|
||||
tgammaf
|
||||
j0f
|
||||
j1f
|
||||
jnf
|
||||
y0f
|
||||
y1f
|
||||
ynf
|
||||
cyl_bessel_i0f
|
||||
cyl_bessel_i1f
|
||||
fmod
|
||||
remainder
|
||||
remquo
|
||||
modf
|
||||
fdim
|
||||
trunc
|
||||
round
|
||||
rint
|
||||
nearbyint
|
||||
ceil
|
||||
floor
|
||||
lrint
|
||||
lround
|
||||
llrint
|
||||
llround
|
||||
fmodf
|
||||
remainderf
|
||||
remquof
|
||||
modff
|
||||
fdimf
|
||||
truncf
|
||||
roundf
|
||||
rintf
|
||||
nearbyintf
|
||||
ceilf
|
||||
floorf
|
||||
lrintf
|
||||
lroundf
|
||||
llrintf
|
||||
llroundf
|
||||
fma
|
||||
abs
|
||||
fabs
|
||||
copysign
|
||||
fmax
|
||||
fmin
|
||||
nan
|
||||
nextafter
|
||||
signbit
|
||||
fmaf
|
||||
abs
|
||||
fabsf
|
||||
copysignf
|
||||
fdividef
|
||||
fmaxf
|
||||
fminf
|
||||
isfinite
|
||||
isinf
|
||||
isnan
|
||||
nanf
|
||||
nextafterf
|
||||
signbit
|
||||
__brev
|
||||
__brevll
|
||||
__clz
|
||||
__clzll
|
||||
__ffs
|
||||
__ffsll
|
||||
__popc
|
||||
__popcll
|
||||
__mul24
|
||||
__umul24
|
||||
__dadd_rn
|
||||
__dsub_rn
|
||||
__dmul_rn
|
||||
__fma_rn
|
||||
__drcp_rn
|
||||
__dsqrt_rn
|
||||
__ddiv_rn
|
||||
__fadd_rn
|
||||
__fsub_rn
|
||||
__fmul_rn
|
||||
__fmaf_rn
|
||||
__frcp_rn
|
||||
__fsqrt_rn
|
||||
__frsqrt_rn
|
||||
__fdiv_rn
|
||||
__fdividef
|
||||
__expf
|
||||
__exp10f
|
||||
__logf
|
||||
__log2f
|
||||
__log10f
|
||||
__sinf
|
||||
__cosf
|
||||
__sincosf
|
||||
__tanf
|
||||
__powf
|
||||
]
|
||||
|
||||
Device conversion functions [
|
||||
__double2float_rd
|
||||
__double2float_rn
|
||||
__double2float_ru
|
||||
__double2float_rz
|
||||
__double2hiint
|
||||
__double2loint
|
||||
__double2int_rd
|
||||
__double2int_rn
|
||||
__double2int_ru
|
||||
__double2int_rz
|
||||
__double2ll_rd
|
||||
__double2ll_rn
|
||||
__double2ll_ru
|
||||
__double2ll_rz
|
||||
__double2uint_rd
|
||||
__double2uint_rn
|
||||
__double2uint_ru
|
||||
__double2uint_rz
|
||||
__double2ull_rd
|
||||
__double2ull_rn
|
||||
__double2ull_ru
|
||||
__double2ull_rz
|
||||
__double_as_longlong
|
||||
__float2int_rd
|
||||
__float2int_rn
|
||||
__float2int_ru
|
||||
__float2int_rz
|
||||
__float2ll_rd
|
||||
__float2ll_rn
|
||||
__float2ll_ru
|
||||
__float2ll_rz
|
||||
__float2uint_rd
|
||||
__float2uint_rn
|
||||
__float2uint_ru
|
||||
__float2uint_rz
|
||||
__float2ull_rd
|
||||
__float2ull_rn
|
||||
__float2ull_ru
|
||||
__float2ull_rz
|
||||
__float_as_int
|
||||
__float_as_uint
|
||||
__hiloint2double
|
||||
__int2double_rn
|
||||
__int2float_rd
|
||||
__int2float_rn
|
||||
__int2float_ru
|
||||
__int2float_rz
|
||||
__int_as_float
|
||||
__ll2double_rd
|
||||
__ll2double_rn
|
||||
__ll2double_ru
|
||||
__ll2double_rz
|
||||
__ll2float_rd
|
||||
__ll2float_rn
|
||||
__ll2float_ru
|
||||
__ll2float_rz
|
||||
__longlong_as_double
|
||||
__uint2double_rn
|
||||
__uint2float_rd
|
||||
__uint2float_rn
|
||||
__uint2float_ru
|
||||
__uint2float_rz
|
||||
__uint_as_float
|
||||
__ull2double_rd
|
||||
__ull2double_rn
|
||||
__ull2double_ru
|
||||
__ull2double_rz
|
||||
__ull2float_rd
|
||||
__ull2float_rn
|
||||
__ull2float_ru
|
||||
__ull2float_rz
|
||||
]
|
||||
|
||||
Device complex type functions [
|
||||
hipCrealf
|
||||
hipCimagf
|
||||
make_hipFloatComplex
|
||||
hipConjf
|
||||
hipCsqabsf
|
||||
hipCaddf
|
||||
hipCsubf
|
||||
hipCmulf
|
||||
hipCdivf
|
||||
hipCabsf
|
||||
hipCreal
|
||||
hipCimag
|
||||
make_hipDoubleComplex
|
||||
hipConj
|
||||
hipCsqabs
|
||||
hipCadd
|
||||
hipCsub
|
||||
hipCmul
|
||||
hipCdiv
|
||||
hipCabs
|
||||
make_hipComplex
|
||||
hipComplexDoubleToFloat
|
||||
hipComplexFloatToDouble
|
||||
hipCfmaf
|
||||
hipCfma
|
||||
]
|
||||
|
||||
Device vector types [
|
||||
make_uchar1
|
||||
make_uchar2
|
||||
make_uchar3
|
||||
make_uchar4
|
||||
make_char1
|
||||
make_char2
|
||||
make_char3
|
||||
make_char4
|
||||
make_ushort1
|
||||
make_ushort2
|
||||
make_ushort3
|
||||
make_ushort4
|
||||
make_short1
|
||||
make_short2
|
||||
make_short3
|
||||
make_short4
|
||||
make_uint1
|
||||
make_uint2
|
||||
make_uint3
|
||||
make_uint4
|
||||
make_int1
|
||||
make_int2
|
||||
make_int3
|
||||
make_int4
|
||||
make_float1
|
||||
make_float2
|
||||
make_float3
|
||||
make_float4
|
||||
make_double1
|
||||
make_double2
|
||||
make_double3
|
||||
make_double4
|
||||
make_ulong1
|
||||
make_ulong2
|
||||
make_ulong3
|
||||
make_ulong4
|
||||
make_long1
|
||||
make_long2
|
||||
make_long3
|
||||
make_long4
|
||||
make_ulonglong1
|
||||
make_ulonglong2
|
||||
make_ulonglong3
|
||||
make_ulonglong4
|
||||
make_longlong1
|
||||
make_longlong2
|
||||
make_longlong3
|
||||
make_longlong4
|
||||
]
|
||||
|
||||
Device surface functions [
|
||||
__hipGetPixelAddr
|
||||
__hipMapToNativeFloat4
|
||||
__hipMapFromNativeFloat4
|
||||
surf1Dread
|
||||
surf1Dwrite
|
||||
surf2Dread
|
||||
surf2Dwrite
|
||||
surf3Dread
|
||||
surf3Dwrite
|
||||
surf1DLayeredread
|
||||
surf1DLayeredwrite
|
||||
surf2DLayeredread
|
||||
surf2DLayeredwrite
|
||||
surfCubemapread
|
||||
surfCubemapwrite
|
||||
surfCubemapLayeredread
|
||||
surfCubemapLayeredwrite
|
||||
]
|
||||
|
||||
Device texture functions [
|
||||
tex1Dfetch
|
||||
tex1D
|
||||
tex2D
|
||||
tex1DLayered
|
||||
tex2DLayered
|
||||
tex3D
|
||||
texCubemap
|
||||
tex1DLod
|
||||
tex2DLod
|
||||
tex1DLayeredLod
|
||||
tex2DLayeredLod
|
||||
tex3DLod
|
||||
texCubemapLod
|
||||
texCubemapLayered
|
||||
texCubemapLayeredLod
|
||||
texCubemapGrad
|
||||
texCubemapLayeredGrad
|
||||
tex1DGrad
|
||||
tex2DGrad
|
||||
tex1DLayeredGrad
|
||||
tex2DLayeredGrad
|
||||
tex3DGrad
|
||||
tex2Dgather
|
||||
]
|
||||
|
||||
Device float16 functions [
|
||||
make_half2
|
||||
__low2half
|
||||
__high2half
|
||||
__half2half2
|
||||
__halves2half2
|
||||
__low2half2
|
||||
__high2half2
|
||||
__lows2half2
|
||||
__highs2half2
|
||||
__lowhigh2highlow
|
||||
__half_as_short
|
||||
__half_as_ushort
|
||||
__short_as_half
|
||||
__ushort_as_half
|
||||
__float2half
|
||||
__float2half_rn
|
||||
__float2half_rz
|
||||
__float2half_rd
|
||||
__float2half_ru
|
||||
__float2half2_rn
|
||||
__floats2half2_rn
|
||||
__float22half2_rn
|
||||
__half2float
|
||||
__low2float
|
||||
__high2float
|
||||
__half22float2
|
||||
__half2int_rn
|
||||
__half2int_rz
|
||||
__half2int_rd
|
||||
__half2int_ru
|
||||
__int2half_rn
|
||||
__int2half_rz
|
||||
__int2half_rd
|
||||
__int2half_ru
|
||||
__half2short_rn
|
||||
__half2short_rz
|
||||
__half2short_rd
|
||||
__half2short_ru
|
||||
__short2half_rn
|
||||
__short2half_rz
|
||||
__short2half_rd
|
||||
__short2half_ru
|
||||
__half2ll_rn
|
||||
__half2ll_rz
|
||||
__half2ll_rd
|
||||
__half2ll_ru
|
||||
__ll2half_rn
|
||||
__ll2half_rz
|
||||
__ll2half_rd
|
||||
__ll2half_ru
|
||||
__half2uint_rn
|
||||
__half2uint_rz
|
||||
__half2uint_rd
|
||||
__half2uint_ru
|
||||
__uint2half_rn
|
||||
__uint2half_rz
|
||||
__uint2half_rd
|
||||
__uint2half_ru
|
||||
__half2ushort_rn
|
||||
__half2ushort_rz
|
||||
__half2ushort_rd
|
||||
__half2ushort_ru
|
||||
__ushort2half_rn
|
||||
__ushort2half_rz
|
||||
__ushort2half_rd
|
||||
__ushort2half_ru
|
||||
__half2ull_rn
|
||||
__half2ull_rz
|
||||
__half2ull_rd
|
||||
__half2ull_ru
|
||||
__ull2half_rn
|
||||
__ull2half_rz
|
||||
__ull2half_rd
|
||||
__ull2half_ru
|
||||
__ldg
|
||||
__ldcg
|
||||
__ldca
|
||||
__ldcs
|
||||
__heq
|
||||
__hne
|
||||
__hle
|
||||
__hge
|
||||
__hlt
|
||||
__hgt
|
||||
__hequ
|
||||
__hneu
|
||||
__hleu
|
||||
__hgeu
|
||||
__hltu
|
||||
__hgtu
|
||||
__heq2
|
||||
__hne2
|
||||
__hle2
|
||||
__hge2
|
||||
__hlt2
|
||||
__hgt2
|
||||
__hequ2
|
||||
__hneu2
|
||||
__hleu2
|
||||
__hgeu2
|
||||
__hltu2
|
||||
__hgtu2
|
||||
__hbeq2
|
||||
__hbne2
|
||||
__hble2
|
||||
__hbge2
|
||||
__hblt2
|
||||
__hbgt2
|
||||
__hbequ2
|
||||
__hbneu2
|
||||
__hbleu2
|
||||
__hbgeu2
|
||||
__hbltu2
|
||||
__hbgtu2
|
||||
__clamp_01
|
||||
__hadd
|
||||
__habs
|
||||
__hsub
|
||||
__hmul
|
||||
__hadd_sat
|
||||
__hsub_sat
|
||||
__hmul_sat
|
||||
__hfma
|
||||
__hfma_sat
|
||||
__hdiv
|
||||
__hadd2
|
||||
__habs2
|
||||
__hsub2
|
||||
__hmul2
|
||||
__hadd2_sat
|
||||
__hsub2_sat
|
||||
__hmul2_sat
|
||||
__hfma2
|
||||
__hfma2_sat
|
||||
__h2div
|
||||
amd_mixed_dot
|
||||
htrunc
|
||||
hceil
|
||||
hfloor
|
||||
hrint
|
||||
hsin
|
||||
hcos
|
||||
hexp
|
||||
hexp2
|
||||
hexp10
|
||||
hlog2
|
||||
hlog
|
||||
hlog10
|
||||
hrcp
|
||||
hrsqrt
|
||||
hsqrt
|
||||
__hisinf
|
||||
__hisnan
|
||||
__hneg
|
||||
h2trunc
|
||||
h2ceil
|
||||
h2floor
|
||||
h2rint
|
||||
h2sin
|
||||
h2cos
|
||||
h2exp
|
||||
h2exp2
|
||||
h2exp10
|
||||
h2log2
|
||||
h2log
|
||||
h2log10
|
||||
h2rcp
|
||||
h2rsqrt
|
||||
h2sqrt
|
||||
__hisinf2
|
||||
__hisnan2
|
||||
__hneg2
|
||||
]
|
||||
@@ -22,11 +22,20 @@ THE SOFTWARE.
|
||||
|
||||
#include "hipAPI.h"
|
||||
|
||||
FileOccurrence::FileOccurrence(std::string file_name, int line_number):
|
||||
file_name{file_name}, line_number{line_number} {}
|
||||
FileOccurrence::FileOccurrence(std::string file_name, int line_number)
|
||||
: file_name{file_name}, line_number{line_number} {}
|
||||
|
||||
TestCaseOccurrence::TestCaseOccurrence(std::string test_case_name, std::string file_name, int line_number):
|
||||
FileOccurrence{file_name, line_number}, test_case_name{test_case_name} {}
|
||||
TestCaseOccurrence::TestCaseOccurrence(std::string test_case_name, std::string file_name,
|
||||
int line_number)
|
||||
: FileOccurrence{file_name, line_number}, test_case_name{test_case_name} {}
|
||||
|
||||
bool operator==(const TestCaseOccurrence& l_test, const TestCaseOccurrence& r_test) {
|
||||
return l_test.test_case_name == r_test.test_case_name;
|
||||
}
|
||||
|
||||
bool operator<(const TestCaseOccurrence& l_test, const TestCaseOccurrence& r_test) {
|
||||
return l_test.test_case_name < r_test.test_case_name;
|
||||
}
|
||||
|
||||
bool operator==(const HipAPI& l_hip_api, const HipAPI& r_hip_api) {
|
||||
return l_hip_api.api_name == r_hip_api.api_name;
|
||||
@@ -36,54 +45,53 @@ bool operator<(const HipAPI& l_hip_api, const HipAPI& r_hip_api) {
|
||||
return l_hip_api.api_name < r_hip_api.api_name;
|
||||
}
|
||||
|
||||
HipAPI::HipAPI(std::string api_name, bool deprecated_flag, std::string api_group_name):
|
||||
api_name{api_name}, deprecated{deprecated_flag}, api_group_name{api_group_name} {}
|
||||
|
||||
std::string HipAPI::getName() const {
|
||||
return api_name;
|
||||
HipAPI::HipAPI(std::string api_name, bool deprecated_flag, std::string api_group_name,
|
||||
std::string file_restriction)
|
||||
: api_name{api_name},
|
||||
deprecated{deprecated_flag},
|
||||
api_group_name{api_group_name},
|
||||
file_restriction{file_restriction} {
|
||||
test_cases.clear();
|
||||
}
|
||||
|
||||
std::string HipAPI::getGroupName() const {
|
||||
return api_group_name;
|
||||
}
|
||||
std::string HipAPI::getName() const { return api_name; }
|
||||
|
||||
int HipAPI::getNumberOfCalls() const {
|
||||
return file_occurrences.size();
|
||||
}
|
||||
std::string HipAPI::getGroupName() const { return api_group_name; }
|
||||
|
||||
int HipAPI::getNumberOfTestCases() const {
|
||||
return test_cases.size();
|
||||
}
|
||||
int HipAPI::getNumberOfCalls() const { return file_occurrences.size(); }
|
||||
|
||||
std::vector<TestCaseOccurrence> HipAPI::getTestCases() const { return test_cases; }
|
||||
|
||||
void HipAPI::addFileOccurrence(FileOccurrence file_occurrence) {
|
||||
file_occurrences.push_back(file_occurrence);
|
||||
}
|
||||
|
||||
void HipAPI::addTestCase(TestCaseOccurrence test_case) {
|
||||
test_cases.push_back(test_case);
|
||||
if (std::find(test_cases.begin(), test_cases.end(), test_case) == test_cases.end()) {
|
||||
test_cases.push_back(test_case);
|
||||
}
|
||||
}
|
||||
|
||||
bool HipAPI::isDeprecated() const
|
||||
{
|
||||
return deprecated;
|
||||
}
|
||||
bool HipAPI::isDeprecated() const { return deprecated; }
|
||||
|
||||
std::string HipAPI::getBasicStatsXML() const
|
||||
{
|
||||
std::string HipAPI::getBasicStatsXML() const {
|
||||
std::stringstream xml_node;
|
||||
xml_node << "\t\t<HIP-API>\n";
|
||||
|
||||
if (!deprecated) {
|
||||
xml_node << "\t\t\t<NAME>" << api_name << "</NAME>\n";
|
||||
} else {
|
||||
xml_node << "\t\t\t<NAME>" << "[DEPRECATED] " << api_name << "</NAME>\n";
|
||||
xml_node << "\t\t\t<NAME>"
|
||||
<< "[DEPRECATED] " << api_name << "</NAME>\n";
|
||||
}
|
||||
|
||||
if (!file_occurrences.empty()) {
|
||||
xml_node << "\t\t\t<NUMBER-OF-API-CALLS>" << file_occurrences.size() << "</NUMBER-OF-API-CALLS>\n";
|
||||
xml_node << "\t\t\t<NUMBER-OF-API-CALLS>" << file_occurrences.size()
|
||||
<< "</NUMBER-OF-API-CALLS>\n";
|
||||
xml_node << "\t\t\t<FILE-OCCURRENCES>\n";
|
||||
for (auto const& file_occurrence: file_occurrences) {
|
||||
xml_node << "\t\t\t\t<FILE-OCCURRENCE>" << file_occurrence.file_name << ":" << file_occurrence.line_number << "</FILE-OCCURRENCE>\n";
|
||||
for (auto const& file_occurrence : file_occurrences) {
|
||||
xml_node << "\t\t\t\t<FILE-OCCURRENCE>" << file_occurrence.file_name << ":"
|
||||
<< file_occurrence.line_number << "</FILE-OCCURRENCE>\n";
|
||||
}
|
||||
xml_node << "\t\t\t</FILE-OCCURRENCES>\n";
|
||||
}
|
||||
@@ -102,13 +110,20 @@ std::string HipAPI::createHTMLReport() const {
|
||||
std::string six_tabs{"\n\t\t\t\t\t\t"};
|
||||
|
||||
html_report << "<html lang=\"en\">";
|
||||
html_report << "<head>" << one_tab << "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">";
|
||||
html_report << one_tab << "<title>" << api_name << " Coverage report</title>" << one_tab << "<link rel=\"stylesheet\" type=\"text/css\" href=\"../resources/coverage.css\">" << one_tab<< "</head>";
|
||||
html_report << one_tab << "<body>" << one_tab << "<table width=\"100%\" border=0 cellspacing=0 cellpadding=0>";
|
||||
html_report << "<head>" << one_tab
|
||||
<< "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">";
|
||||
html_report << one_tab << "<title>" << api_name << " Coverage report</title>" << one_tab
|
||||
<< "<link rel=\"stylesheet\" type=\"text/css\" href=\"../resources/coverage.css\">"
|
||||
<< one_tab << "</head>";
|
||||
html_report << one_tab << "<body>" << one_tab
|
||||
<< "<table width=\"100%\" border=0 cellspacing=0 cellpadding=0>";
|
||||
html_report << two_tabs << "<tr><td class=\"title\">" << api_name << " Coverage report</td></tr>";
|
||||
html_report << two_tabs << "<tr><td class=\"ruler\"><img src=\"../resources/glass.png\" width=3 height=3></td></tr>\n";
|
||||
html_report << two_tabs << "<tr>" << three_tabs << "<td width=\"100%\">" << four_tabs << "<table cellpading=1 border=0 width=\"100%\"";
|
||||
|
||||
html_report << two_tabs
|
||||
<< "<tr><td class=\"ruler\"><img src=\"../resources/glass.png\" width=3 "
|
||||
"height=3></td></tr>\n";
|
||||
html_report << two_tabs << "<tr>" << three_tabs << "<td width=\"100%\">" << four_tabs
|
||||
<< "<table cellpading=1 border=0 width=\"100%\"";
|
||||
|
||||
html_report << five_tabs << "<tr>";
|
||||
html_report << six_tabs << "<td width=\"70%\"</td>";
|
||||
html_report << six_tabs << "<td width=\"10%\"></td>";
|
||||
@@ -124,7 +139,8 @@ std::string HipAPI::createHTMLReport() const {
|
||||
|
||||
html_report << five_tabs << "<tr>";
|
||||
html_report << six_tabs << "<td class=\"headerItem\">Calls within test source files:</td>";
|
||||
html_report << six_tabs << "<td class=\"headerCovTableEntry\">" << file_occurrences.size() << "</td>";
|
||||
html_report << six_tabs << "<td class=\"headerCovTableEntry\">" << file_occurrences.size()
|
||||
<< "</td>";
|
||||
html_report << six_tabs << "<td></td>";
|
||||
html_report << six_tabs << "<td></td>";
|
||||
html_report << five_tabs << "</tr>";
|
||||
@@ -135,13 +151,16 @@ std::string HipAPI::createHTMLReport() const {
|
||||
html_report << six_tabs << "<td></td>";
|
||||
html_report << six_tabs << "<td></td>";
|
||||
html_report << five_tabs << "</tr>";
|
||||
|
||||
html_report << five_tabs << "<tr><td><img src=\"../resources/glass.png\" width=3 height=3></td></tr>";
|
||||
|
||||
html_report << five_tabs
|
||||
<< "<tr><td><img src=\"../resources/glass.png\" width=3 height=3></td></tr>";
|
||||
html_report << four_tabs << "</table>";
|
||||
html_report << three_tabs << "</td>";
|
||||
html_report << two_tabs << "</tr>";
|
||||
|
||||
html_report << two_tabs << "<tr><td class=\"ruler\"><img src=\"../resources/glass.png\" width=3 height=3></td></tr>\n";
|
||||
html_report << two_tabs
|
||||
<< "<tr><td class=\"ruler\"><img src=\"../resources/glass.png\" width=3 "
|
||||
"height=3></td></tr>\n";
|
||||
html_report << one_tab << "</table>";
|
||||
|
||||
html_report << one_tab << "<center>";
|
||||
@@ -160,23 +179,29 @@ std::string HipAPI::createHTMLReport() const {
|
||||
html_report << three_tabs << "<td class=\"tableHead\">Line number</td>";
|
||||
html_report << two_tabs << "</tr>";
|
||||
|
||||
for (auto const& test_case: test_cases) {
|
||||
for (auto const& test_case : test_cases) {
|
||||
html_report << two_tabs << "<tr>";
|
||||
html_report << three_tabs << "<td class=\"coverFile\">" << test_case.test_case_name << "</td>";
|
||||
html_report << three_tabs << "<td class=\"coverFile\">" << test_case.test_case_name
|
||||
<< "</td>";
|
||||
html_report << three_tabs << "<td class=\"coverFile\">" << test_case.file_name << "</td>";
|
||||
html_report << three_tabs << "<td class=\"headerCovTableEntry\">" << test_case.line_number << "</td>";
|
||||
html_report << three_tabs << "<td class=\"headerCovTableEntry\">" << test_case.line_number
|
||||
<< "</td>";
|
||||
html_report << two_tabs << "</tr>";
|
||||
}
|
||||
} else {
|
||||
html_report << two_tabs << "<tr>";
|
||||
html_report << three_tabs << "<td class=\"headerItem\" style=\"text-align:center\"><br>There are no test cases detected within doxygen comments.</td>";
|
||||
html_report << three_tabs
|
||||
<< "<td class=\"headerItem\" style=\"text-align:center\"><br>There are no test "
|
||||
"cases detected within doxygen comments.</td>";
|
||||
html_report << two_tabs << "</tr>";
|
||||
}
|
||||
html_report << one_tab << "</table>";
|
||||
|
||||
html_report << one_tab << "<br>";
|
||||
html_report << one_tab << "<table width=\"100%\" border=0 cellspacing=0 cellpadding=0>";
|
||||
html_report << two_tabs << "<tr><td class=\"ruler\"><img src=\"../resources/glass.png\" width=3 height=3></td></tr>";
|
||||
html_report
|
||||
<< two_tabs
|
||||
<< "<tr><td class=\"ruler\"><img src=\"../resources/glass.png\" width=3 height=3></td></tr>";
|
||||
html_report << one_tab << "</table>";
|
||||
|
||||
// Add info about API occurrences in the test files.
|
||||
@@ -192,15 +217,19 @@ std::string HipAPI::createHTMLReport() const {
|
||||
html_report << three_tabs << "<td class=\"tableHead\">Line number</td>";
|
||||
html_report << two_tabs << "</tr>";
|
||||
|
||||
for (auto const& file_occurrence: file_occurrences) {
|
||||
for (auto const& file_occurrence : file_occurrences) {
|
||||
html_report << two_tabs << "<tr>";
|
||||
html_report << three_tabs << "<td class=\"coverFile\">" << file_occurrence.file_name << "</td>";
|
||||
html_report << three_tabs << "<td class=\"headerCovTableEntry\">" << file_occurrence.line_number << "</td>";
|
||||
html_report << three_tabs << "<td class=\"coverFile\">" << file_occurrence.file_name
|
||||
<< "</td>";
|
||||
html_report << three_tabs << "<td class=\"headerCovTableEntry\">"
|
||||
<< file_occurrence.line_number << "</td>";
|
||||
html_report << two_tabs << "</tr>";
|
||||
}
|
||||
} else {
|
||||
html_report << two_tabs << "<tr>";
|
||||
html_report << three_tabs << "<td class=\"headerItem\" style=\"text-align:center\"><br>There are no occurrences within test source files.</td>";
|
||||
html_report << three_tabs
|
||||
<< "<td class=\"headerItem\" style=\"text-align:center\"><br>There are no "
|
||||
"occurrences within test source files.</td>";
|
||||
html_report << two_tabs << "</tr>";
|
||||
}
|
||||
html_report << one_tab << "</table>";
|
||||
@@ -208,7 +237,9 @@ std::string HipAPI::createHTMLReport() const {
|
||||
|
||||
html_report << one_tab << "<br>";
|
||||
html_report << one_tab << "<table width=\"100%\" border=0 cellspacing=0 cellpadding=0>";
|
||||
html_report << two_tabs << "<tr><td class=\"ruler\"><img src=\"../resources/glass.png\" width=3 height=3></td></tr>";
|
||||
html_report
|
||||
<< two_tabs
|
||||
<< "<tr><td class=\"ruler\"><img src=\"../resources/glass.png\" width=3 height=3></td></tr>";
|
||||
|
||||
time_t now{time(nullptr)};
|
||||
std::string date{asctime(gmtime(&now))};
|
||||
@@ -220,3 +251,5 @@ std::string HipAPI::createHTMLReport() const {
|
||||
|
||||
return html_report.str();
|
||||
}
|
||||
|
||||
std::string HipAPI::getFileRestriction() const { return file_restriction; }
|
||||
|
||||
@@ -23,6 +23,7 @@ THE SOFTWARE.
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
/*
|
||||
Helper class used to store information in what file has HIP API been detected,
|
||||
@@ -40,6 +41,9 @@ Helper class used to store information in what file has the API Test Case been d
|
||||
and on what line of code in that file.
|
||||
*/
|
||||
class TestCaseOccurrence : public FileOccurrence {
|
||||
friend bool operator==(const TestCaseOccurrence& l_test, const TestCaseOccurrence& r_test);
|
||||
friend bool operator<(const TestCaseOccurrence& l_test, const TestCaseOccurrence& r_test);
|
||||
|
||||
public:
|
||||
std::string test_case_name;
|
||||
TestCaseOccurrence(std::string test_case_name, std::string file_name, int line_number);
|
||||
@@ -55,18 +59,23 @@ class HipAPI {
|
||||
friend bool operator<(const HipAPI& l_hip_api, const HipAPI& r_hip_api);
|
||||
|
||||
public:
|
||||
HipAPI(std::string api_name, bool deprecated_flag, std::string api_group_name);
|
||||
HipAPI(std::string api_name, bool deprecated_flag, std::string api_group_name,
|
||||
std::string file_restriction = "");
|
||||
std::string getName() const;
|
||||
std::string getGroupName() const;
|
||||
int getNumberOfCalls() const;
|
||||
int getNumberOfTestCases() const;
|
||||
std::vector<TestCaseOccurrence> getTestCases() const;
|
||||
void addFileOccurrence(FileOccurrence file_occurence);
|
||||
void addTestCase(TestCaseOccurrence test_case);
|
||||
bool isDeprecated() const;
|
||||
std::string getBasicStatsXML() const;
|
||||
std::string createHTMLReport() const;
|
||||
std::string getFileRestriction() const;
|
||||
std::vector<std::string> device_groups;
|
||||
|
||||
private:
|
||||
std::string api_name;
|
||||
std::string file_restriction;
|
||||
int number_of_calls;
|
||||
bool deprecated;
|
||||
std::string api_group_name;
|
||||
|
||||
@@ -42,13 +42,34 @@ void findAPICallInFile(HipAPI& hip_api, std::string test_module_file) {
|
||||
std::string api_call_with_assert{"(" + hip_api.getName() + "("};
|
||||
std::string api_call_with_assignment{"= " + hip_api.getName() + "("};
|
||||
std::string api_call_with_parameter{", " + hip_api.getName() + "("};
|
||||
std::string api_call_with_return{"return " + hip_api.getName() + "("};
|
||||
std::string api_call_in_line("{ " + hip_api.getName() + "(");
|
||||
std::string api_member{"." + hip_api.getName() + "("};
|
||||
std::string api_newline{" " + hip_api.getName() + "("};
|
||||
std::string api_templated{" " + hip_api.getName() + "<"};
|
||||
|
||||
std::string api_restriction{hip_api.getFileRestriction()};
|
||||
bool found_restriction{false};
|
||||
|
||||
while (std::getline(test_module_file_handler, line)) {
|
||||
++line_number;
|
||||
|
||||
if (api_restriction != "" && line.find(api_restriction) != std::string::npos) {
|
||||
found_restriction = true;
|
||||
}
|
||||
|
||||
if ((line.find(api_call_with_assert) != std::string::npos) ||
|
||||
(line.find(api_call_with_assignment) != std::string::npos) ||
|
||||
(line.find(api_call_with_parameter) != std::string::npos)) {
|
||||
hip_api.addFileOccurrence(FileOccurrence(test_module_file, line_number));
|
||||
(line.find(api_call_with_parameter) != std::string::npos) ||
|
||||
(line.find(api_call_with_return) != std::string::npos) ||
|
||||
(line.find(api_call_in_line) != std::string::npos) ||
|
||||
(line.find(api_member) != std::string::npos) ||
|
||||
(line.find(api_newline) != std::string::npos) ||
|
||||
(line.find(hip_api.getName() + "(") == 0) ||
|
||||
(line.find(api_templated) != std::string::npos)) {
|
||||
if (api_restriction == "" || found_restriction) {
|
||||
hip_api.addFileOccurrence(FileOccurrence(test_module_file, line_number));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +80,7 @@ void findAPICallInFile(HipAPI& hip_api, std::string test_module_file) {
|
||||
Used to find all HIP API test cases within the passed test .cc files.
|
||||
Matching test case is detected when the HIP API in defined within doxygen comment.
|
||||
*/
|
||||
void findAPITestCaseInFile(HipAPI& hip_api, std::string test_module_file) {
|
||||
void findAPITestCaseInFileByDoxygen(HipAPI& hip_api, std::string test_module_file) {
|
||||
std::fstream test_module_file_handler;
|
||||
test_module_file_handler.open(test_module_file);
|
||||
|
||||
@@ -80,7 +101,10 @@ void findAPITestCaseInFile(HipAPI& hip_api, std::string test_module_file) {
|
||||
}
|
||||
|
||||
if (hip_api.getName() != current_api_name) {
|
||||
continue;
|
||||
if (std::find(hip_api.device_groups.begin(), hip_api.device_groups.end(), current_api_name) ==
|
||||
hip_api.device_groups.end()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (line.find(ref_test_case) != std::string::npos) {
|
||||
@@ -99,15 +123,45 @@ void findAPITestCaseInFile(HipAPI& hip_api, std::string test_module_file) {
|
||||
test_module_file_handler.close();
|
||||
}
|
||||
|
||||
/*
|
||||
Used to find all HIP API test cases within the passed test .cc files.
|
||||
Matching test case is detected when the HIP API in defined within doxygen comment.
|
||||
*/
|
||||
void findAPITestCaseInFileByAPIName(HipAPI& hip_api, std::string test_module_file) {
|
||||
std::fstream test_module_file_handler;
|
||||
test_module_file_handler.open(test_module_file);
|
||||
|
||||
int line_number{0};
|
||||
std::string line;
|
||||
|
||||
std::string test_case_definition{"TEST_CASE("};
|
||||
std::string test_case{"None"};
|
||||
|
||||
while (std::getline(test_module_file_handler, line)) {
|
||||
++line_number;
|
||||
|
||||
if (line.find(test_case_definition) != std::string::npos) {
|
||||
test_case = line.substr(line.find("\"") + 1);
|
||||
test_case = test_case.substr(0, test_case.find("\""));
|
||||
if (test_case.find("_" + hip_api.getName() + "_") != std::string::npos) {
|
||||
hip_api.addTestCase(TestCaseOccurrence{test_case, test_module_file, line_number});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test_module_file_handler.close();
|
||||
}
|
||||
|
||||
/*
|
||||
Used to iterate through all passed test .cc files and search for passed
|
||||
HIP API instance. This instance shall be used to update occurrences.
|
||||
*/
|
||||
void searchForAPI(HipAPI& hip_api, std::vector<std::string>& test_module_files) {
|
||||
std::cout << "Searching for " << hip_api.getName() << " in test module files." << std::endl;
|
||||
for (auto const& test_module_file: test_module_files) {
|
||||
for (auto const& test_module_file : test_module_files) {
|
||||
findAPICallInFile(hip_api, test_module_file);
|
||||
findAPITestCaseInFile(hip_api, test_module_file);
|
||||
findAPITestCaseInFileByDoxygen(hip_api, test_module_file);
|
||||
findAPITestCaseInFileByAPIName(hip_api, test_module_file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +169,7 @@ void searchForAPI(HipAPI& hip_api, std::vector<std::string>& test_module_files)
|
||||
Used to extract all HIP APIs from the passed header file.
|
||||
*/
|
||||
std::vector<HipAPI> extractHipAPIs(std::string& hip_api_header_file,
|
||||
std::vector<std::string>& api_group_names, bool start_groups) {
|
||||
std::vector<std::string>& api_group_names, bool start_groups) {
|
||||
std::fstream hip_header_file_handler;
|
||||
hip_header_file_handler.open(hip_api_header_file);
|
||||
|
||||
@@ -148,8 +202,9 @@ std::vector<HipAPI> extractHipAPIs(std::string& hip_api_header_file,
|
||||
++line_number;
|
||||
|
||||
// Declarations of the HIP APIs start after the HIP API group has been defined.
|
||||
if ((line.find(group_definition) != std::string::npos || line.find(add_group_definition) != std::string::npos)
|
||||
&& line.find(start_of_api_groups) != std::string::npos) {
|
||||
if ((line.find(group_definition) != std::string::npos ||
|
||||
line.find(add_group_definition) != std::string::npos) &&
|
||||
line.find(start_of_api_groups) != std::string::npos) {
|
||||
api_group_names_start = true;
|
||||
continue;
|
||||
}
|
||||
@@ -167,24 +222,21 @@ std::vector<HipAPI> extractHipAPIs(std::string& hip_api_header_file,
|
||||
/*
|
||||
If the API is deprecated, raise a flag and go to the
|
||||
next line where the API is declared.
|
||||
*/
|
||||
*/
|
||||
if (line.find(deprecated_line) != std::string::npos) {
|
||||
std::getline(hip_header_file_handler, line);
|
||||
++line_number;
|
||||
deprecated_flag = true;
|
||||
} else {
|
||||
deprecated_flag = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.find(group_definition) != std::string::npos) {
|
||||
std::string group_name = line.substr(line.find(group_definition) + group_definition.length() + 1);
|
||||
std::string group_name =
|
||||
line.substr(line.find(group_definition) + group_definition.length() + 1);
|
||||
group_name = group_name.substr(group_name.find(' ') + 1);
|
||||
api_group_names.push_back(group_name);
|
||||
api_group_names_tracker.push_back(group_name);
|
||||
}
|
||||
else if (line.find(add_group_definition) != std::string::npos)
|
||||
{
|
||||
std::string group_name = line.substr(line.find(add_group_definition) + add_group_definition.length() + 1);
|
||||
} else if (line.find(add_group_definition) != std::string::npos) {
|
||||
std::string group_name =
|
||||
line.substr(line.find(add_group_definition) + add_group_definition.length() + 1);
|
||||
group_name = group_name.substr(group_name.find(' ') + 1);
|
||||
api_group_names.push_back(group_name);
|
||||
api_group_names_tracker.push_back(group_name);
|
||||
@@ -196,7 +248,9 @@ std::vector<HipAPI> extractHipAPIs(std::string& hip_api_header_file,
|
||||
to track the last defined group, because of the nested cases.
|
||||
*/
|
||||
if (line.find(end_group_definition) != std::string::npos) {
|
||||
api_group_names_tracker.pop_back();
|
||||
if (!api_group_names_tracker.empty()) {
|
||||
api_group_names_tracker.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -207,16 +261,14 @@ std::vector<HipAPI> extractHipAPIs(std::string& hip_api_header_file,
|
||||
- Extract the name from that substring by finding the last "hip".
|
||||
Avoid comments.
|
||||
*/
|
||||
if (line.find(hip_api_prefix) != std::string::npos &&
|
||||
line.find("(") != std::string::npos &&
|
||||
line.find(" ") != 0 &&
|
||||
line.find(" *") != 0) {
|
||||
if (line.find(hip_api_prefix) != std::string::npos && line.find("(") != std::string::npos &&
|
||||
line.find(" ") != 0 && line.find(" *") != 0) {
|
||||
std::string api_name_no_brackets{line.substr(0, line.find("("))};
|
||||
/*
|
||||
If there is no hip substring, then there is no valid API in that line.
|
||||
*/
|
||||
if (api_name_no_brackets.rfind(hip_api_prefix) == std::string::npos) {
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -233,13 +285,15 @@ std::vector<HipAPI> extractHipAPIs(std::string& hip_api_header_file,
|
||||
If the API is not present in the global list of HIP APIs, add it.
|
||||
*/
|
||||
HipAPI hip_api{api_name, deprecated_flag, api_group_names_tracker.back()};
|
||||
if(std::find(hip_apis.begin(), hip_apis.end(), hip_api) == hip_apis.end())
|
||||
{
|
||||
hip_apis.push_back(hip_api);
|
||||
if (std::find(hip_apis.begin(), hip_apis.end(), hip_api) == hip_apis.end()) {
|
||||
hip_apis.push_back(hip_api);
|
||||
}
|
||||
} else {
|
||||
std::cout << "[SKIP_FROM_COV] Group not detected for \"" << api_name << "\" in file \""
|
||||
<< hip_api_header_file << "\", line " << line_number << std::endl;
|
||||
<< hip_api_header_file << "\", line " << line_number << std::endl;
|
||||
}
|
||||
if (deprecated_flag) {
|
||||
deprecated_flag = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -248,14 +302,83 @@ std::vector<HipAPI> extractHipAPIs(std::string& hip_api_header_file,
|
||||
return hip_apis;
|
||||
}
|
||||
|
||||
/*
|
||||
Used to extract all HIP APIs from the passed header file.
|
||||
*/
|
||||
std::vector<HipAPI> extractDeviceAPIs(std::string& apis_list_file,
|
||||
std::vector<std::string>& api_group_names) {
|
||||
std::fstream apis_list_file_handler;
|
||||
apis_list_file_handler.open(apis_list_file);
|
||||
|
||||
std::string line;
|
||||
std::vector<HipAPI> device_apis;
|
||||
|
||||
/*
|
||||
Each HIP API has prefix hip in the name. Groups are marked with @defgroup, and the
|
||||
main group that shall be considered is HIP API. Before that group is defined, lines
|
||||
of code shall not be considered.
|
||||
*/
|
||||
int line_number{0};
|
||||
bool group_start{false};
|
||||
bool device_groups_start{false};
|
||||
std::string restriction{""};
|
||||
std::string file_restriction_definition{"File restriction: "};
|
||||
std::string device_groups_definition{"Device groups: ("};
|
||||
std::vector<std::string> device_groups;
|
||||
|
||||
while (std::getline(apis_list_file_handler, line)) {
|
||||
++line_number;
|
||||
|
||||
if (line.find("[") != std::string::npos) {
|
||||
std::string group_name = line.substr(0, line.rfind(" "));
|
||||
api_group_names.push_back(group_name);
|
||||
group_start = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.find("]") != std::string::npos) {
|
||||
group_start = false;
|
||||
device_groups.clear();
|
||||
restriction = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.find(file_restriction_definition) != std::string::npos) {
|
||||
restriction =
|
||||
line.substr(line.find(file_restriction_definition) + file_restriction_definition.size());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.find(device_groups_definition) != std::string::npos) {
|
||||
std::getline(apis_list_file_handler, line);
|
||||
while (line.find(")") == std::string::npos) {
|
||||
std::string group_name = line;
|
||||
group_name.erase(std::remove(group_name.begin(), group_name.end(), ' '), group_name.end());
|
||||
device_groups.push_back(group_name);
|
||||
std::getline(apis_list_file_handler, line);
|
||||
}
|
||||
std::getline(apis_list_file_handler, line);
|
||||
}
|
||||
|
||||
if (group_start) {
|
||||
std::string api_name = line.substr(line.rfind(" ") + 1);
|
||||
HipAPI hip_api{api_name, false, api_group_names.back(), restriction};
|
||||
hip_api.device_groups = device_groups;
|
||||
device_apis.push_back(hip_api);
|
||||
}
|
||||
}
|
||||
|
||||
apis_list_file_handler.close();
|
||||
return device_apis;
|
||||
}
|
||||
|
||||
/*
|
||||
Used to extract test .cc files from the passed tests root directory.
|
||||
Goes through all subdirectories and searches for .cc and .hh files for
|
||||
HIP API invocations.
|
||||
Implements BFS algorithm to avoid recursion.
|
||||
*/
|
||||
std::vector<std::string> extractTestModuleFiles(std::string& tests_root_directory)
|
||||
{
|
||||
std::vector<std::string> extractTestModuleFiles(std::string& tests_root_directory) {
|
||||
std::vector<std::string> directory_queue;
|
||||
directory_queue.push_back(tests_root_directory);
|
||||
std::vector<std::string> test_module_files;
|
||||
@@ -263,11 +386,11 @@ std::vector<std::string> extractTestModuleFiles(std::string& tests_root_director
|
||||
while (!directory_queue.empty()) {
|
||||
std::string processed_entry = directory_queue.back();
|
||||
directory_queue.pop_back();
|
||||
for (const auto& entry: std::filesystem::directory_iterator(processed_entry)) {
|
||||
for (const auto& entry : std::filesystem::directory_iterator(processed_entry)) {
|
||||
if (std::filesystem::is_directory(entry.path())) {
|
||||
directory_queue.push_back(entry.path());
|
||||
} else {
|
||||
if (entry.path().string().find(".cc") != std::string::npos ||
|
||||
if (entry.path().string().find(".cc") != std::string::npos ||
|
||||
entry.path().string().find(".hh") != std::string::npos) {
|
||||
test_module_files.push_back(entry.path());
|
||||
}
|
||||
@@ -278,7 +401,6 @@ std::vector<std::string> extractTestModuleFiles(std::string& tests_root_director
|
||||
return test_module_files;
|
||||
}
|
||||
|
||||
std::string findAbsolutePathOfFile(std::string file_path)
|
||||
{
|
||||
std::string findAbsolutePathOfFile(std::string file_path) {
|
||||
return std::filesystem::canonical(std::filesystem::absolute(file_path));
|
||||
}
|
||||
|
||||
@@ -25,8 +25,12 @@ THE SOFTWARE.
|
||||
#include "hipAPIGroup.h"
|
||||
|
||||
void findAPICallInFile(HipAPI& hip_api, std::string test_module_file);
|
||||
void findAPITestCaseInFile(HipAPI& hip_api, std::string test_module_file);
|
||||
void findAPITestCaseInFileByDoxygen(HipAPI& hip_api, std::string test_module_file);
|
||||
void findAPITestCaseInFileByAPIName(HipAPI& hip_api, std::string test_module_file);
|
||||
void searchForAPI(HipAPI& hip_api, std::vector<std::string>& test_module_files);
|
||||
std::vector<HipAPI> extractHipAPIs(std::string& hip_api_header_file, std::vector<std::string>& api_group_names, bool start_groups);
|
||||
std::vector<HipAPI> extractHipAPIs(std::string& hip_api_header_file,
|
||||
std::vector<std::string>& api_group_names, bool start_groups);
|
||||
std::vector<HipAPI> extractDeviceAPIs(std::string& apis_list_file,
|
||||
std::vector<std::string>& api_group_names);
|
||||
std::vector<std::string> extractTestModuleFiles(std::string& tests_root_directory);
|
||||
std::string findAbsolutePathOfFile(std::string file_path);
|
||||
|
||||
@@ -26,11 +26,14 @@ bool operator==(const HipAPIGroup& l_hip_api_group, const HipAPIGroup& r_hip_api
|
||||
return l_hip_api_group.group_name == r_hip_api_group.group_name;
|
||||
}
|
||||
|
||||
HipAPIGroup::HipAPIGroup(std::string group_name, std::vector<HipAPI>& hip_apis):
|
||||
group_name{group_name}, number_of_api_calls{0}, percentage_of_called_apis{0.f},
|
||||
total_number_of_apis{0}, number_of_test_cases{0}
|
||||
{
|
||||
for (auto const& hip_api: hip_apis) {
|
||||
HipAPIGroup::HipAPIGroup(std::string group_name, std::vector<HipAPI>& hip_apis)
|
||||
: group_name{group_name},
|
||||
number_of_api_calls{0},
|
||||
percentage_of_called_apis{0.f},
|
||||
total_number_of_apis{0},
|
||||
number_of_test_cases{0} {
|
||||
std::vector<TestCaseOccurrence> test_cases;
|
||||
for (auto const& hip_api : hip_apis) {
|
||||
if (hip_api.getGroupName() != group_name) {
|
||||
continue;
|
||||
}
|
||||
@@ -46,47 +49,43 @@ HipAPIGroup::HipAPIGroup(std::string group_name, std::vector<HipAPI>& hip_apis):
|
||||
}
|
||||
|
||||
number_of_api_calls += hip_api.getNumberOfCalls();
|
||||
number_of_test_cases += hip_api.getNumberOfTestCases();
|
||||
|
||||
std::vector<TestCaseOccurrence> api_test_cases = hip_api.getTestCases();
|
||||
test_cases.insert(test_cases.end(), api_test_cases.begin(), api_test_cases.end());
|
||||
}
|
||||
|
||||
std::sort(test_cases.begin(), test_cases.end());
|
||||
auto last = std::unique(test_cases.begin(), test_cases.end());
|
||||
test_cases.erase(last, test_cases.end());
|
||||
number_of_test_cases = test_cases.size();
|
||||
|
||||
total_number_of_apis = called_apis.size() + not_called_apis.size() + deprecated_apis.size();
|
||||
if (not_called_apis.empty()) {
|
||||
percentage_of_called_apis = 100.f;
|
||||
} else {
|
||||
percentage_of_called_apis = 100.f * called_apis.size() / (total_number_of_apis - deprecated_apis.size());
|
||||
percentage_of_called_apis =
|
||||
100.f * called_apis.size() / (total_number_of_apis - deprecated_apis.size());
|
||||
}
|
||||
}
|
||||
|
||||
std::string HipAPIGroup::getName() const {
|
||||
return group_name;
|
||||
}
|
||||
std::string HipAPIGroup::getName() const { return group_name; }
|
||||
|
||||
int HipAPIGroup::getTotalNumberOfAPIs() const {
|
||||
return total_number_of_apis;
|
||||
}
|
||||
int HipAPIGroup::getTotalNumberOfAPIs() const { return total_number_of_apis; }
|
||||
|
||||
int HipAPIGroup::getTotalNumberOfCalls() const {
|
||||
return number_of_api_calls;
|
||||
}
|
||||
int HipAPIGroup::getTotalNumberOfCalls() const { return number_of_api_calls; }
|
||||
|
||||
int HipAPIGroup::getTotalNumberOfTestCases() const {
|
||||
return number_of_test_cases;
|
||||
}
|
||||
int HipAPIGroup::getTotalNumberOfTestCases() const { return number_of_test_cases; }
|
||||
|
||||
int HipAPIGroup::getNumberOfCalledAPIs() const {
|
||||
return called_apis.size();
|
||||
}
|
||||
int HipAPIGroup::getNumberOfCalledAPIs() const { return called_apis.size(); }
|
||||
|
||||
int HipAPIGroup::getNumberOfNotCalledAPIs() const {
|
||||
return not_called_apis.size();
|
||||
}
|
||||
int HipAPIGroup::getNumberOfNotCalledAPIs() const { return not_called_apis.size(); }
|
||||
|
||||
int HipAPIGroup::getNumberOfDeprecatedAPIs() const {
|
||||
return deprecated_apis.size();
|
||||
}
|
||||
int HipAPIGroup::getNumberOfDeprecatedAPIs() const { return deprecated_apis.size(); }
|
||||
|
||||
float HipAPIGroup::getPercentageOfCalledAPIs() const {
|
||||
return percentage_of_called_apis;
|
||||
float HipAPIGroup::getPercentageOfCalledAPIs() const { return percentage_of_called_apis; }
|
||||
|
||||
bool HipAPIGroup::isDeprecated() const {
|
||||
return (deprecated_apis.size() == total_number_of_apis) ? true : false;
|
||||
}
|
||||
|
||||
std::string HipAPIGroup::getBasicStatsXML() const {
|
||||
@@ -100,16 +99,18 @@ std::string HipAPIGroup::getBasicStatsXML() const {
|
||||
|
||||
xml_node << "\n\t<COVERAGE-RESULTS>";
|
||||
xml_node << "\n\t\t<TOTAL-NUMBER-OF-APIs>" << total_number_of_apis << "</TOTAL-NUMBER-OF-APIs>";
|
||||
xml_node << "\n\t\t<TOTAL-NUMBER-OF-API-CALLS>" << number_of_api_calls << "</TOTAL-NUMBER-OF-API-CALLS>";
|
||||
xml_node << "\n\t\t<TOTAL-NUMBER-OF-API-CALLS>" << number_of_api_calls
|
||||
<< "</TOTAL-NUMBER-OF-API-CALLS>";
|
||||
xml_node << "\n\t\t<CALLED-APIs>" << called_apis.size() << "</CALLED-APIs>";
|
||||
xml_node << "\n\t\t<NOT-CALLED-APIs>" << not_called_apis.size() << "</NOT-CALLED-APIs>";
|
||||
xml_node << "\n\t\t<DEPRECATED-APIs>" << deprecated_apis.size() << "</DEPRECATED-APIs>";
|
||||
xml_node << "\n\t\t<COVERAGE-PERCENTAGE>" << percentage_of_called_apis << "%</COVERAGE-PERCENTAGE>";
|
||||
xml_node << "\n\t\t<COVERAGE-PERCENTAGE>" << percentage_of_called_apis
|
||||
<< "%</COVERAGE-PERCENTAGE>";
|
||||
xml_node << "\n\t</COVERAGE-RESULTS>";
|
||||
|
||||
if (!called_apis.empty()) {
|
||||
xml_node << "\n\t<LIST-OF-CALLED-APIs>\n";
|
||||
for (auto const& hip_api: called_apis) {
|
||||
for (auto const& hip_api : called_apis) {
|
||||
xml_node << hip_api.getBasicStatsXML();
|
||||
}
|
||||
xml_node << "\t</LIST-OF-CALLED-APIs>";
|
||||
@@ -117,7 +118,7 @@ std::string HipAPIGroup::getBasicStatsXML() const {
|
||||
|
||||
if (!not_called_apis.empty()) {
|
||||
xml_node << "\n\t<LIST-OF-NOT-CALLED-APIs>\n";
|
||||
for (auto const& hip_api: not_called_apis) {
|
||||
for (auto const& hip_api : not_called_apis) {
|
||||
xml_node << hip_api.getBasicStatsXML();
|
||||
}
|
||||
xml_node << "\t</LIST-OF-NOT-CALLED-APIs>";
|
||||
@@ -125,7 +126,7 @@ std::string HipAPIGroup::getBasicStatsXML() const {
|
||||
|
||||
if (!deprecated_apis.empty()) {
|
||||
xml_node << "\n\t<DEPRECATED-APIs>\n";
|
||||
for (auto const& hip_api: deprecated_apis) {
|
||||
for (auto const& hip_api : deprecated_apis) {
|
||||
xml_node << hip_api.getBasicStatsXML();
|
||||
}
|
||||
xml_node << "\t</DEPRECATED-APIs>";
|
||||
@@ -135,8 +136,7 @@ std::string HipAPIGroup::getBasicStatsXML() const {
|
||||
return xml_node.str();
|
||||
}
|
||||
|
||||
std::string HipAPIGroup::getBasicStatsHTML() const
|
||||
{
|
||||
std::string HipAPIGroup::getBasicStatsHTML() const {
|
||||
std::stringstream html_object;
|
||||
std::string two_tabs{"\n\t\t"};
|
||||
std::string three_tabs{"\n\t\t\t"};
|
||||
@@ -158,29 +158,42 @@ std::string HipAPIGroup::getBasicStatsHTML() const
|
||||
color_bar = "resources/emerald.png";
|
||||
}
|
||||
|
||||
if (isDeprecated()) {
|
||||
font_class = "coverDeprecated";
|
||||
}
|
||||
|
||||
html_object << two_tabs << "<tr>";
|
||||
html_object << three_tabs << "<td class=\"coverFile\"><a href=\"testModules/" << group_name << ".html\">" << group_name << "</a></td>";
|
||||
html_object << three_tabs << "<td class=\"" << font_class << "\">" << total_number_of_apis << "</td>";
|
||||
html_object << three_tabs << "<td class=\"" << font_class << "\">" << number_of_api_calls << "</td>";
|
||||
html_object << three_tabs << "<td class=\"" << font_class << "\">" << number_of_test_cases << "</td>";
|
||||
html_object << three_tabs << "<td class=\"" << font_class << "\">" << called_apis.size() << "</td>";
|
||||
html_object << three_tabs << "<td class=\"" << font_class << "\">" << not_called_apis.size() << "</td>";
|
||||
html_object << three_tabs << "<td class=\"" << font_class << "\">" << deprecated_apis.size() << "</td>";
|
||||
html_object << three_tabs << "<td class=\"" << font_class << "\">" << std::fixed << std::setprecision(2) << percentage_of_called_apis << "%</td>";
|
||||
html_object << three_tabs << "<td class=\"coverFile\"><a href=\"testModules/" << group_name
|
||||
<< ".html\">" << group_name << "</a></td>";
|
||||
html_object << three_tabs << "<td class=\"" << font_class << "\">" << total_number_of_apis
|
||||
<< "</td>";
|
||||
html_object << three_tabs << "<td class=\"" << font_class << "\">" << number_of_api_calls
|
||||
<< "</td>";
|
||||
html_object << three_tabs << "<td class=\"" << font_class << "\">" << number_of_test_cases
|
||||
<< "</td>";
|
||||
html_object << three_tabs << "<td class=\"" << font_class << "\">" << called_apis.size()
|
||||
<< "</td>";
|
||||
html_object << three_tabs << "<td class=\"" << font_class << "\">" << not_called_apis.size()
|
||||
<< "</td>";
|
||||
html_object << three_tabs << "<td class=\"" << font_class << "\">" << deprecated_apis.size()
|
||||
<< "</td>";
|
||||
html_object << three_tabs << "<td class=\"" << font_class << "\">" << std::fixed
|
||||
<< std::setprecision(2) << percentage_of_called_apis << "%</td>";
|
||||
|
||||
html_object << three_tabs << "<td class=\"coverBar\" align=\"center\">";
|
||||
html_object << four_tabs << "<table border=0 cellspacing=0 cellpadding=1>";
|
||||
html_object << five_tabs << "<tr><td class=\"coverBarOutline\"><img src=\"";
|
||||
html_object << color_bar << "\" width=" << percentage_of_called_apis<< " height=10 alt=\"" << percentage_of_called_apis << "%\">";
|
||||
html_object << "<img src=\"resources/snow.png\" width=" << 100.f - percentage_of_called_apis << " height=10 alt=\"" << percentage_of_called_apis << "\"></td></tr></table>";
|
||||
html_object << color_bar << "\" width=" << percentage_of_called_apis << " height=10 alt=\""
|
||||
<< percentage_of_called_apis << "%\">";
|
||||
html_object << "<img src=\"resources/snow.png\" width=" << 100.f - percentage_of_called_apis
|
||||
<< " height=10 alt=\"" << percentage_of_called_apis << "\"></td></tr></table>";
|
||||
html_object << four_tabs << "</td>";
|
||||
html_object << three_tabs << "</tr>";
|
||||
|
||||
return html_object.str();
|
||||
}
|
||||
|
||||
std::string HipAPIGroup::createHTMLReport() const
|
||||
{
|
||||
std::string HipAPIGroup::createHTMLReport() const {
|
||||
std::stringstream html_report;
|
||||
std::string one_tab{"\n\t"};
|
||||
std::string two_tabs{"\n\t\t"};
|
||||
@@ -190,14 +203,22 @@ std::string HipAPIGroup::createHTMLReport() const
|
||||
std::string six_tabs{"\n\t\t\t\t\t\t"};
|
||||
|
||||
html_report << "<html lang=\"en\">";
|
||||
html_report << "<head>" << one_tab << "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">";
|
||||
html_report << "<head>" << one_tab
|
||||
<< "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">";
|
||||
html_report << one_tab << "<title>" << group_name << " Coverage report</title>";
|
||||
html_report << one_tab << "<link rel=\"stylesheet\" type=\"text/css\" href=\"../resources/coverage.css\">" << one_tab<< "</head>";
|
||||
html_report << one_tab << "<body>" << one_tab << "<table width=\"100%\" border=0 cellspacing=0 cellpadding=0>";
|
||||
html_report << two_tabs << "<tr><td class=\"title\">" << group_name << " Coverage report</td></tr>";
|
||||
html_report << two_tabs << "<tr><td class=\"ruler\"><img src=\"../resources/glass.png\" width=3 height=3></td></tr>\n";
|
||||
html_report << two_tabs << "<tr>" << three_tabs << "<td width=\"100%\">" << four_tabs << "<table cellpading=1 border=0 width=\"100%\"";
|
||||
|
||||
html_report << one_tab
|
||||
<< "<link rel=\"stylesheet\" type=\"text/css\" href=\"../resources/coverage.css\">"
|
||||
<< one_tab << "</head>";
|
||||
html_report << one_tab << "<body>" << one_tab
|
||||
<< "<table width=\"100%\" border=0 cellspacing=0 cellpadding=0>";
|
||||
html_report << two_tabs << "<tr><td class=\"title\">" << group_name
|
||||
<< " Coverage report</td></tr>";
|
||||
html_report << two_tabs
|
||||
<< "<tr><td class=\"ruler\"><img src=\"../resources/glass.png\" width=3 "
|
||||
"height=3></td></tr>\n";
|
||||
html_report << two_tabs << "<tr>" << three_tabs << "<td width=\"100%\">" << four_tabs
|
||||
<< "<table cellpading=1 border=0 width=\"100%\"";
|
||||
|
||||
html_report << five_tabs << "<tr>";
|
||||
html_report << six_tabs << "<td width=\"70%\"></td>";
|
||||
html_report << six_tabs << "<td width=\"10%\" class=\"headerCovTableHead\">Value</td>";
|
||||
@@ -206,37 +227,44 @@ std::string HipAPIGroup::createHTMLReport() const
|
||||
|
||||
html_report << five_tabs << "<tr>";
|
||||
html_report << six_tabs << "<td class=\"headerItem\">Total number of detected HIP APIs:</td>";
|
||||
html_report << six_tabs << "<td class=\"headerCovTableEntry\">" << total_number_of_apis << "</td>";
|
||||
html_report << six_tabs << "<td class=\"headerCovTableEntry\">" << total_number_of_apis
|
||||
<< "</td>";
|
||||
html_report << six_tabs << "<td></td>";
|
||||
html_report << five_tabs << "</tr>";
|
||||
|
||||
html_report << five_tabs << "<tr>";
|
||||
html_report << six_tabs << "<td class=\"headerItem\">HIP API calls within test source files:</td>";
|
||||
html_report << six_tabs
|
||||
<< "<td class=\"headerItem\">HIP API calls within test source files:</td>";
|
||||
html_report << six_tabs << "<td class=\"headerCovTableEntry\">" << number_of_api_calls << "</td>";
|
||||
html_report << six_tabs << "<td></td>";
|
||||
html_report << five_tabs << "</tr>";
|
||||
|
||||
html_report << five_tabs << "<tr>";
|
||||
html_report << six_tabs << "<td class=\"headerItem\">Total number of test cases:</td>";
|
||||
html_report << six_tabs << "<td class=\"headerCovTableEntry\">" << number_of_test_cases << "</td>";
|
||||
html_report << six_tabs << "<td class=\"headerCovTableEntry\">" << number_of_test_cases
|
||||
<< "</td>";
|
||||
html_report << six_tabs << "<td></td>";
|
||||
html_report << five_tabs << "</tr>";
|
||||
|
||||
html_report << five_tabs << "<tr>";
|
||||
html_report << six_tabs << "<td class=\"headerItem\">HIP APIs that are called at least once:</td>";
|
||||
html_report << six_tabs
|
||||
<< "<td class=\"headerItem\">HIP APIs that are called at least once:</td>";
|
||||
html_report << six_tabs << "<td class=\"headerCovTableEntry\">" << called_apis.size() << "</td>";
|
||||
html_report << six_tabs << "<td></td>";
|
||||
html_report << five_tabs << "</tr>";
|
||||
|
||||
html_report << five_tabs << "<tr>";
|
||||
html_report << six_tabs << "<td class=\"headerItem\">HIP APIs that are not called at all:</td>";
|
||||
html_report << six_tabs << "<td class=\"headerCovTableEntry\">" << not_called_apis.size() << "</td>";
|
||||
html_report << six_tabs << "<td class=\"headerCovTableEntry\">" << not_called_apis.size()
|
||||
<< "</td>";
|
||||
html_report << six_tabs << "<td></td>";
|
||||
html_report << five_tabs << "</tr>";
|
||||
|
||||
html_report << five_tabs << "<tr>";
|
||||
html_report << six_tabs << "<td class=\"headerItem\">HIP APIs that are marked as deprecated:</td>";
|
||||
html_report << six_tabs << "<td class=\"headerCovTableEntry\">" << deprecated_apis.size() << "</td>";
|
||||
html_report << six_tabs
|
||||
<< "<td class=\"headerItem\">HIP APIs that are marked as deprecated:</td>";
|
||||
html_report << six_tabs << "<td class=\"headerCovTableEntry\">" << deprecated_apis.size()
|
||||
<< "</td>";
|
||||
html_report << six_tabs << "<td></td>";
|
||||
html_report << five_tabs << "</tr>";
|
||||
|
||||
@@ -251,17 +279,23 @@ std::string HipAPIGroup::createHTMLReport() const
|
||||
}
|
||||
|
||||
html_report << five_tabs << "<tr>";
|
||||
html_report << six_tabs << "<td class=\"headerItem\">Test coverage by implemented tests for the HIP APIs:</td>";
|
||||
html_report << six_tabs << "<td class=\"" << font_class << "\">" << std::fixed << std::setprecision(2) << percentage_of_called_apis << "%</td>";
|
||||
html_report
|
||||
<< six_tabs
|
||||
<< "<td class=\"headerItem\">Test coverage by implemented tests for the HIP APIs:</td>";
|
||||
html_report << six_tabs << "<td class=\"" << font_class << "\">" << std::fixed
|
||||
<< std::setprecision(2) << percentage_of_called_apis << "%</td>";
|
||||
html_report << six_tabs << "<td></td>";
|
||||
html_report << five_tabs << "</tr>";
|
||||
|
||||
html_report << five_tabs << "<tr><td><img src=\"../resources/glass.png\" width=3 height=3></td></tr>";
|
||||
html_report << five_tabs
|
||||
<< "<tr><td><img src=\"../resources/glass.png\" width=3 height=3></td></tr>";
|
||||
html_report << four_tabs << "</table>";
|
||||
html_report << three_tabs << "</td>";
|
||||
html_report << two_tabs << "</tr>";
|
||||
|
||||
html_report << two_tabs << "<tr><td class=\"ruler\"><img src=\"../resources/glass.png\" width=3 height=3></td></tr>\n";
|
||||
html_report << two_tabs
|
||||
<< "<tr><td class=\"ruler\"><img src=\"../resources/glass.png\" width=3 "
|
||||
"height=3></td></tr>\n";
|
||||
html_report << one_tab << "</table>";
|
||||
|
||||
// Add info about Test module APIs.
|
||||
@@ -279,9 +313,10 @@ std::string HipAPIGroup::createHTMLReport() const
|
||||
html_report << five_tabs << "<tr>";
|
||||
html_report << six_tabs << "<td class=\"tableHead\">Called APIs</td>";
|
||||
html_report << five_tabs << "</tr>";
|
||||
for (auto const& hip_api: called_apis) {
|
||||
for (auto const& hip_api : called_apis) {
|
||||
html_report << five_tabs << "<tr>";
|
||||
html_report << six_tabs << "<td class=\"coverFile\"><a href=\"../testAPIs/" << hip_api.getName() << ".html\">" << hip_api.getName() << "</a></td>";
|
||||
html_report << six_tabs << "<td class=\"coverFile\"><a href=\"../testAPIs/" << hip_api.getName()
|
||||
<< ".html\">" << hip_api.getName() << "</a></td>";
|
||||
html_report << five_tabs << "</tr>";
|
||||
}
|
||||
|
||||
@@ -293,9 +328,10 @@ std::string HipAPIGroup::createHTMLReport() const
|
||||
html_report << five_tabs << "<tr>";
|
||||
html_report << six_tabs << "<td class=\"tableHead\">Not called APIs</td>";
|
||||
html_report << five_tabs << "</tr>";
|
||||
for (auto const& hip_api: not_called_apis) {
|
||||
for (auto const& hip_api : not_called_apis) {
|
||||
html_report << five_tabs << "<tr>";
|
||||
html_report << six_tabs << "<td class=\"coverFile\"><a href=\"../testAPIs/" << hip_api.getName() << ".html\">" << hip_api.getName() << "</a></td>";
|
||||
html_report << six_tabs << "<td class=\"coverFile\"><a href=\"../testAPIs/" << hip_api.getName()
|
||||
<< ".html\">" << hip_api.getName() << "</a></td>";
|
||||
html_report << five_tabs << "</tr>";
|
||||
}
|
||||
html_report << four_tabs << "</table>";
|
||||
@@ -306,9 +342,10 @@ std::string HipAPIGroup::createHTMLReport() const
|
||||
html_report << five_tabs << "<tr>";
|
||||
html_report << six_tabs << "<td class=\"tableHead\">Deprecated APIs</td>";
|
||||
html_report << five_tabs << "</tr>";
|
||||
for (auto const& hip_api: deprecated_apis) {
|
||||
for (auto const& hip_api : deprecated_apis) {
|
||||
html_report << five_tabs << "<tr>";
|
||||
html_report << six_tabs << "<td class=\"coverFile\"><a href=\"../testAPIs/" << hip_api.getName() << ".html\">" << hip_api.getName() << "</a></td>";
|
||||
html_report << six_tabs << "<td class=\"coverFile\"><a href=\"../testAPIs/" << hip_api.getName()
|
||||
<< ".html\">" << hip_api.getName() << "</a></td>";
|
||||
html_report << five_tabs << "</tr>";
|
||||
}
|
||||
html_report << four_tabs << "</table>";
|
||||
@@ -321,7 +358,9 @@ std::string HipAPIGroup::createHTMLReport() const
|
||||
html_report << one_tab << "<br>";
|
||||
|
||||
html_report << one_tab << "<table width=\"100%\" border=0 cellspacing=0 cellpadding=0>";
|
||||
html_report << two_tabs << "<tr><td class=\"ruler\"><img src=\"../resources/glass.png\" width=3 height=3></td></tr>";
|
||||
html_report
|
||||
<< two_tabs
|
||||
<< "<tr><td class=\"ruler\"><img src=\"../resources/glass.png\" width=3 height=3></td></tr>";
|
||||
|
||||
time_t now{time(nullptr)};
|
||||
std::string date{asctime(gmtime(&now))};
|
||||
|
||||
@@ -21,10 +21,9 @@ THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "hipAPI.h"
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
|
||||
class HipAPIGroup{
|
||||
class HipAPIGroup {
|
||||
friend bool operator==(const HipAPIGroup& l_hip_api_group, const HipAPIGroup& r_hip_api_group);
|
||||
|
||||
public:
|
||||
@@ -40,6 +39,8 @@ class HipAPIGroup{
|
||||
std::string getBasicStatsXML() const;
|
||||
std::string getBasicStatsHTML() const;
|
||||
std::string createHTMLReport() const;
|
||||
bool isDeprecated() const;
|
||||
|
||||
private:
|
||||
std::string group_name;
|
||||
int total_number_of_apis;
|
||||
|
||||
@@ -22,10 +22,11 @@ THE SOFTWARE.
|
||||
|
||||
#include "reportGenerators.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int main(int argc, char** argv) {
|
||||
if (argc != 2) {
|
||||
std::cout << "Please provide the path to the cloned HIP/include/ directory as an argument! Only one argument supported." << std::endl;
|
||||
std::cout << "Please provide the path to the cloned HIP/include/ directory as an argument! "
|
||||
"Only one argument supported."
|
||||
<< std::endl;
|
||||
std::cout << "\tExample: ./generateHipAPICoverage /workspace/user1/HIP/include/" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
@@ -34,33 +35,44 @@ int main(int argc, char** argv)
|
||||
Relative paths to all needed files, as it is expected that the application
|
||||
is called from the HIP/tests/catch/coverage directory.
|
||||
*/
|
||||
std::string hip_api_header_file{findAbsolutePathOfFile(hip_include_path + "/hip/hip_runtime_api.h")};
|
||||
std::string hip_api_header_file{
|
||||
findAbsolutePathOfFile(hip_include_path + "/hip/hip_runtime_api.h")};
|
||||
std::string hip_rtc_header_file{findAbsolutePathOfFile(hip_include_path + "/hip/hiprtc.h")};
|
||||
std::string tests_root_directory{findAbsolutePathOfFile("../../catch")};
|
||||
std::string device_api_file{"device_api_list.txt"};
|
||||
|
||||
std::vector<std::string> api_group_names;
|
||||
// Extract all HIP API declarations from the HIP API header file.
|
||||
std::vector<HipAPI> hip_apis{extractHipAPIs(hip_api_header_file, api_group_names, false)};
|
||||
std::cout << "Number of detected HIP APIs from " << hip_api_header_file << ": " << hip_apis.size() << std::endl;
|
||||
std::cout << "Number of detected HIP APIs from " << hip_api_header_file << ": " << hip_apis.size()
|
||||
<< std::endl;
|
||||
|
||||
std::vector<HipAPI> hip_rtc_apis{extractHipAPIs(hip_rtc_header_file, api_group_names, true)};
|
||||
std::cout << "Number of detected HIP APIs from " << hip_rtc_header_file << ": " << hip_rtc_apis.size() << std::endl;
|
||||
std::cout << "Number of detected HIP APIs from " << hip_rtc_header_file << ": "
|
||||
<< hip_rtc_apis.size() << std::endl;
|
||||
hip_apis.insert(hip_apis.end(), hip_rtc_apis.begin(), hip_rtc_apis.end());
|
||||
|
||||
std::vector<HipAPI> device_apis{extractDeviceAPIs(device_api_file, api_group_names)};
|
||||
std::cout << "Number of detected device APIs from " << device_api_file << ": "
|
||||
<< device_apis.size() << std::endl;
|
||||
hip_apis.insert(hip_apis.end(), device_apis.begin(), device_apis.end());
|
||||
|
||||
// Extract all test module .cc files that shall be used for API searching.
|
||||
std::cout << "Searching for HIP API calls in source files within " << tests_root_directory << "." << std::endl;
|
||||
std::cout << "Searching for HIP API calls in source files within " << tests_root_directory << "."
|
||||
<< std::endl;
|
||||
std::vector<std::string> test_module_files{extractTestModuleFiles(tests_root_directory)};
|
||||
|
||||
// Search for each HIP API in the extracted test .cc files.
|
||||
for(HipAPI& hip_api: hip_apis) {
|
||||
for (HipAPI& hip_api : hip_apis) {
|
||||
searchForAPI(hip_api, test_module_files);
|
||||
}
|
||||
|
||||
std::vector<HipAPIGroup> hip_api_groups;
|
||||
for (auto const& api_group_name: api_group_names) {
|
||||
for (auto const& api_group_name : api_group_names) {
|
||||
HipAPIGroup hip_api_group{api_group_name, hip_apis};
|
||||
// Avoid having duplicated groups.
|
||||
if (std::find(hip_api_groups.begin(), hip_api_groups.end(), hip_api_group) == hip_api_groups.end()) {
|
||||
if (std::find(hip_api_groups.begin(), hip_api_groups.end(), hip_api_group) ==
|
||||
hip_api_groups.end()) {
|
||||
hip_api_groups.push_back(hip_api_group);
|
||||
}
|
||||
}
|
||||
@@ -68,7 +80,8 @@ int main(int argc, char** argv)
|
||||
std::cout << "Generating XML report files." << std::endl;
|
||||
generateXMLReportFiles(hip_apis, hip_api_groups);
|
||||
std::cout << "Generating HTML report files." << std::endl;
|
||||
generateHTMLReportFiles(hip_apis, hip_api_groups, tests_root_directory, hip_api_header_file, hip_rtc_header_file);
|
||||
generateHTMLReportFiles(hip_apis, hip_api_groups, tests_root_directory, hip_api_header_file,
|
||||
hip_rtc_header_file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -22,38 +22,43 @@ THE SOFTWARE.
|
||||
|
||||
#include "reportGenerators.h"
|
||||
|
||||
BasicAPIStats::BasicAPIStats(std::vector<HipAPIGroup>& hip_api_groups):
|
||||
number_of_called_apis{0}, number_of_not_called_apis{0},
|
||||
number_of_deprecated_apis{0}, total_number_of_api_calls{0},
|
||||
total_number_of_test_cases{0}
|
||||
{
|
||||
for (auto const& hip_api_group: hip_api_groups) {
|
||||
BasicAPIStats::BasicAPIStats(std::vector<HipAPIGroup>& hip_api_groups)
|
||||
: number_of_called_apis{0},
|
||||
number_of_not_called_apis{0},
|
||||
number_of_deprecated_apis{0},
|
||||
total_number_of_api_calls{0},
|
||||
total_number_of_test_cases{0} {
|
||||
for (auto const& hip_api_group : hip_api_groups) {
|
||||
number_of_called_apis += hip_api_group.getNumberOfCalledAPIs();
|
||||
number_of_not_called_apis += hip_api_group.getNumberOfNotCalledAPIs();
|
||||
number_of_deprecated_apis += hip_api_group.getNumberOfDeprecatedAPIs();
|
||||
total_number_of_api_calls += hip_api_group.getTotalNumberOfCalls();
|
||||
total_number_of_test_cases += hip_api_group.getTotalNumberOfTestCases();
|
||||
}
|
||||
total_number_of_apis = number_of_called_apis + number_of_not_called_apis + number_of_deprecated_apis;
|
||||
tests_coverage_percentage = 100.f * number_of_called_apis / (number_of_called_apis + number_of_not_called_apis);
|
||||
total_number_of_apis =
|
||||
number_of_called_apis + number_of_not_called_apis + number_of_deprecated_apis;
|
||||
tests_coverage_percentage =
|
||||
100.f * number_of_called_apis / (number_of_called_apis + number_of_not_called_apis);
|
||||
}
|
||||
|
||||
float BasicAPIStats::getLowCoverageLimit() const {
|
||||
return 40.f;
|
||||
}
|
||||
float BasicAPIStats::getLowCoverageLimit() const { return 40.f; }
|
||||
|
||||
float BasicAPIStats::getMediumCoverageLimit() const {
|
||||
return 80.f;
|
||||
}
|
||||
float BasicAPIStats::getMediumCoverageLimit() const { return 80.f; }
|
||||
|
||||
void generateXMLReportFiles(std::vector<HipAPI>& hip_apis, std::vector<HipAPIGroup>& hip_api_groups) {
|
||||
void generateXMLReportFiles(std::vector<HipAPI>& hip_apis,
|
||||
std::vector<HipAPIGroup>& hip_api_groups) {
|
||||
BasicAPIStats basic_stats{hip_api_groups};
|
||||
|
||||
std::cout << "Total number of HIP API calls: " << basic_stats.total_number_of_api_calls << std::endl;
|
||||
std::cout << "Number of the HIP APIs that are called at least once: " << basic_stats.number_of_called_apis << std::endl;
|
||||
std::cout << "Number of the HIP APIs that are not called at all: " << basic_stats.number_of_not_called_apis << std::endl;
|
||||
std::cout << "Number of the HIP APIs that are marked as deprecated: " << basic_stats.number_of_deprecated_apis << std::endl;
|
||||
std::cout << "Test coverage by implemented tests, for the HIP APIs that are not marked as deprecated: ";
|
||||
std::cout << "Total number of HIP API calls: " << basic_stats.total_number_of_api_calls
|
||||
<< std::endl;
|
||||
std::cout << "Number of the HIP APIs that are called at least once: "
|
||||
<< basic_stats.number_of_called_apis << std::endl;
|
||||
std::cout << "Number of the HIP APIs that are not called at all: "
|
||||
<< basic_stats.number_of_not_called_apis << std::endl;
|
||||
std::cout << "Number of the HIP APIs that are marked as deprecated: "
|
||||
<< basic_stats.number_of_deprecated_apis << std::endl;
|
||||
std::cout
|
||||
<< "Test coverage by implemented tests, for the HIP APIs that are not marked as deprecated: ";
|
||||
std::cout << basic_stats.tests_coverage_percentage << "%" << std::endl;
|
||||
|
||||
/*
|
||||
@@ -71,36 +76,51 @@ void generateXMLReportFiles(std::vector<HipAPI>& hip_apis, std::vector<HipAPIGro
|
||||
|
||||
coverage_report << "<COVERAGE-RESULTS>\n";
|
||||
|
||||
coverage_report << "\t<TOTAL-NUMBER-OF-APIs>\n\t\t<DESCRIPTION>Total number of detected HIP APIs.</DESCRIPTION>";
|
||||
coverage_report << "\n\t\t<NUMBER>" << hip_apis.size() << "</NUMBER>\n\t</TOTAL-NUMBER-OF-APIs>\n";
|
||||
coverage_report << "\t<TOTAL-NUMBER-OF-APIs>\n\t\t<DESCRIPTION>Total number of detected HIP "
|
||||
"APIs.</DESCRIPTION>";
|
||||
coverage_report << "\n\t\t<NUMBER>" << hip_apis.size()
|
||||
<< "</NUMBER>\n\t</TOTAL-NUMBER-OF-APIs>\n";
|
||||
|
||||
coverage_report << "\t<TOTAL-NUMBER-OF-API-CALLS>\n\t\t<DESCRIPTION>Total number of HIP API calls within test source files.</DESCRIPTION>";
|
||||
coverage_report << "\n\t\t<NUMBER>" << basic_stats.total_number_of_api_calls << "</NUMBER>\n\t</TOTAL-NUMBER-OF-API-CALLS>\n";
|
||||
coverage_report << "\t<TOTAL-NUMBER-OF-API-CALLS>\n\t\t<DESCRIPTION>Total number of HIP API "
|
||||
"calls within test source files.</DESCRIPTION>";
|
||||
coverage_report << "\n\t\t<NUMBER>" << basic_stats.total_number_of_api_calls
|
||||
<< "</NUMBER>\n\t</TOTAL-NUMBER-OF-API-CALLS>\n";
|
||||
|
||||
coverage_report << "\t<CALLED-APIs>\n\t\t<DESCRIPTION>Number of the HIP APIs that are called at least once.</DESCRIPTION>";
|
||||
coverage_report << "\n\t\t<NUMBER>" << basic_stats.number_of_called_apis << "</NUMBER>\n\t</CALLED-APIs>\n";
|
||||
coverage_report << "\t<CALLED-APIs>\n\t\t<DESCRIPTION>Number of the HIP APIs that are called at "
|
||||
"least once.</DESCRIPTION>";
|
||||
coverage_report << "\n\t\t<NUMBER>" << basic_stats.number_of_called_apis
|
||||
<< "</NUMBER>\n\t</CALLED-APIs>\n";
|
||||
|
||||
coverage_report << "\t<NOT-CALLED-APIs>\n\t\t<DESCRIPTION>Number of the HIP APIs that are not called at all.</DESCRIPTION>";
|
||||
coverage_report << "\n\t\t<NUMBER>" << basic_stats.number_of_not_called_apis << "</NUMBER>\n\t</NOT-CALLED-APIs>\n";
|
||||
coverage_report << "\t<NOT-CALLED-APIs>\n\t\t<DESCRIPTION>Number of the HIP APIs that are not "
|
||||
"called at all.</DESCRIPTION>";
|
||||
coverage_report << "\n\t\t<NUMBER>" << basic_stats.number_of_not_called_apis
|
||||
<< "</NUMBER>\n\t</NOT-CALLED-APIs>\n";
|
||||
|
||||
coverage_report << "\t<DEPRECATED-APIs>\n\t\t<DESCRIPTION>Number of the HIP APIs that are marked as deprecated.</DESCRIPTION>";
|
||||
coverage_report << "\n\t\t<NUMBER>" << basic_stats.number_of_deprecated_apis << "</NUMBER>\n\t</DEPRECATED-APIs>\n";
|
||||
coverage_report << "\t<DEPRECATED-APIs>\n\t\t<DESCRIPTION>Number of the HIP APIs that are marked "
|
||||
"as deprecated.</DESCRIPTION>";
|
||||
coverage_report << "\n\t\t<NUMBER>" << basic_stats.number_of_deprecated_apis
|
||||
<< "</NUMBER>\n\t</DEPRECATED-APIs>\n";
|
||||
|
||||
coverage_report << "\t<COVERAGE-PERCENTAGE>\n\t\t<DESCRIPTION>Test coverage by implemented tests for the HIP APIs that are not marked as deprecated.</DESCRIPTION>";
|
||||
coverage_report << "\n\t\t<VALUE>" << basic_stats.tests_coverage_percentage << "%</VALUE>\n\t</COVERAGE-PERCENTAGE>";
|
||||
coverage_report << "\t<COVERAGE-PERCENTAGE>\n\t\t<DESCRIPTION>Test coverage by implemented tests "
|
||||
"for the HIP APIs that are not marked as deprecated.</DESCRIPTION>";
|
||||
coverage_report << "\n\t\t<VALUE>" << basic_stats.tests_coverage_percentage
|
||||
<< "%</VALUE>\n\t</COVERAGE-PERCENTAGE>";
|
||||
|
||||
coverage_report << "\n</COVERAGE-RESULTS>";
|
||||
|
||||
for (auto const& hip_api_group: hip_api_groups) {
|
||||
coverage_report << hip_api_group.getBasicStatsHTML();
|
||||
for (auto const& hip_api_group : hip_api_groups) {
|
||||
coverage_report << hip_api_group.getBasicStatsHTML();
|
||||
}
|
||||
|
||||
coverage_report.close();
|
||||
std::cout << "Generated XML report file " << findAbsolutePathOfFile(report_file_name) << std::endl;
|
||||
std::cout << "Generated XML report file " << findAbsolutePathOfFile(report_file_name)
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
void generateHTMLReportFiles(std::vector<HipAPI>& hip_apis, std::vector<HipAPIGroup>& hip_api_groups,
|
||||
std::string tests_root_directory, std::string hipApiHeaderFile, std::string hip_rtc_header_file) {
|
||||
void generateHTMLReportFiles(std::vector<HipAPI>& hip_apis,
|
||||
std::vector<HipAPIGroup>& hip_api_groups,
|
||||
std::string tests_root_directory, std::string hipApiHeaderFile,
|
||||
std::string hip_rtc_header_file) {
|
||||
BasicAPIStats basic_stats{hip_api_groups};
|
||||
|
||||
std::fstream coverage_report;
|
||||
@@ -130,17 +150,26 @@ void generateHTMLReportFiles(std::vector<HipAPI>& hip_apis, std::vector<HipAPIGr
|
||||
source, as it is much more clear.
|
||||
*/
|
||||
coverage_report << "<html lang=\"en\">";
|
||||
coverage_report << "<head>" << one_tab << "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">";
|
||||
coverage_report << "<head>" << one_tab
|
||||
<< "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">";
|
||||
coverage_report << one_tab << "<title>HIP API Coverage report</title>";
|
||||
coverage_report << one_tab << "<link rel=\"stylesheet\" type=\"text/css\" href=\"resources/coverage.css\">" << one_tab << "</head>";
|
||||
coverage_report << one_tab << "<body>" << one_tab << "<table width=\"100%\" border=0 cellspacing=0 cellpadding=0>";
|
||||
coverage_report << one_tab
|
||||
<< "<link rel=\"stylesheet\" type=\"text/css\" href=\"resources/coverage.css\">"
|
||||
<< one_tab << "</head>";
|
||||
coverage_report << one_tab << "<body>" << one_tab
|
||||
<< "<table width=\"100%\" border=0 cellspacing=0 cellpadding=0>";
|
||||
coverage_report << two_tabs << "<tr><td class=\"title\">HIP API Coverage report</td></tr>";
|
||||
coverage_report << two_tabs << "<tr><td class=\"ruler\"><img src=\"resources/glass.png\" width=3 height=3></td></tr>\n";
|
||||
coverage_report << two_tabs << "<tr>" << three_tabs << "<td width=\"100%\">" << four_tabs << "<table cellpading=1 border=0 width=\"100%\"";
|
||||
|
||||
coverage_report
|
||||
<< two_tabs
|
||||
<< "<tr><td class=\"ruler\"><img src=\"resources/glass.png\" width=3 height=3></td></tr>\n";
|
||||
coverage_report << two_tabs << "<tr>" << three_tabs << "<td width=\"100%\">" << four_tabs
|
||||
<< "<table cellpading=1 border=0 width=\"100%\"";
|
||||
|
||||
coverage_report << five_tabs << "<tr>";
|
||||
coverage_report << six_tabs << "<td width=\"20%\" class=\"headerItem\">Catch2 tests location:</td>";
|
||||
coverage_report << six_tabs << "<td width=\"30%\" class=\"headerValue\">" << tests_root_directory << "</td>";
|
||||
coverage_report << six_tabs
|
||||
<< "<td width=\"20%\" class=\"headerItem\">Catch2 tests location:</td>";
|
||||
coverage_report << six_tabs << "<td width=\"30%\" class=\"headerValue\">" << tests_root_directory
|
||||
<< "</td>";
|
||||
coverage_report << six_tabs << "<td width=\"20%\"></td>";
|
||||
coverage_report << six_tabs << "<td width=\"10%\" class=\"headerCovTableHead\">Value</td>";
|
||||
coverage_report << six_tabs << "<td width=\"20%\"></td>";
|
||||
@@ -150,15 +179,18 @@ void generateHTMLReportFiles(std::vector<HipAPI>& hip_apis, std::vector<HipAPIGr
|
||||
coverage_report << six_tabs << "<td class=\"headerItem\">Source files included:</td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerValue\">" << hipApiHeaderFile << "</td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerItem\">Total number of detected HIP APIs:</td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerCovTableEntry\">" << basic_stats.total_number_of_apis << "</td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerCovTableEntry\">"
|
||||
<< basic_stats.total_number_of_apis << "</td>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << five_tabs << "</tr>";
|
||||
|
||||
coverage_report << five_tabs << "<tr>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerValue\">" << hip_rtc_header_file << "</td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerItem\">HIP API calls within test source files:</td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerCovTableEntry\">" << basic_stats.total_number_of_api_calls << "</td>";
|
||||
coverage_report << six_tabs
|
||||
<< "<td class=\"headerItem\">HIP API calls within test source files:</td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerCovTableEntry\">"
|
||||
<< basic_stats.total_number_of_api_calls << "</td>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << five_tabs << "</tr>";
|
||||
|
||||
@@ -166,31 +198,38 @@ void generateHTMLReportFiles(std::vector<HipAPI>& hip_apis, std::vector<HipAPIGr
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerItem\">Total number of test cases:</td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerCovTableEntry\">" << basic_stats.total_number_of_test_cases << "</td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerCovTableEntry\">"
|
||||
<< basic_stats.total_number_of_test_cases << "</td>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << five_tabs << "</tr>";
|
||||
|
||||
coverage_report << five_tabs << "<tr>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerItem\">HIP APIs that are called at least once:</td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerCovTableEntry\">" << basic_stats.number_of_called_apis << "</td>";
|
||||
coverage_report << six_tabs
|
||||
<< "<td class=\"headerItem\">HIP APIs that are called at least once:</td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerCovTableEntry\">"
|
||||
<< basic_stats.number_of_called_apis << "</td>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << five_tabs << "</tr>";
|
||||
|
||||
coverage_report << five_tabs << "<tr>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerItem\">HIP APIs that are not called at all:</td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerCovTableEntry\">" << basic_stats.number_of_not_called_apis << "</td>";
|
||||
coverage_report << six_tabs
|
||||
<< "<td class=\"headerItem\">HIP APIs that are not called at all:</td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerCovTableEntry\">"
|
||||
<< basic_stats.number_of_not_called_apis << "</td>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << five_tabs << "</tr>";
|
||||
|
||||
coverage_report << five_tabs << "<tr>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerItem\">HIP APIs that are marked as deprecated:</td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerCovTableEntry\">" << basic_stats.number_of_deprecated_apis << "</td>";
|
||||
coverage_report << six_tabs
|
||||
<< "<td class=\"headerItem\">HIP APIs that are marked as deprecated:</td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerCovTableEntry\">"
|
||||
<< basic_stats.number_of_deprecated_apis << "</td>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << five_tabs << "</tr>";
|
||||
|
||||
@@ -198,29 +237,32 @@ void generateHTMLReportFiles(std::vector<HipAPI>& hip_apis, std::vector<HipAPIGr
|
||||
std::string font_class;
|
||||
if (basic_stats.tests_coverage_percentage < basic_stats.getLowCoverageLimit()) {
|
||||
font_class = "headerCovTableEntryLo";
|
||||
}
|
||||
else if (basic_stats.tests_coverage_percentage < basic_stats.getMediumCoverageLimit()) {
|
||||
} else if (basic_stats.tests_coverage_percentage < basic_stats.getMediumCoverageLimit()) {
|
||||
font_class = "headerCovTableEntryMed";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
font_class = "headerCovTableEntryHi";
|
||||
}
|
||||
|
||||
coverage_report << five_tabs << "<tr>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << six_tabs << "<td class=\"headerItem\">Test coverage by implemented tests for the HIP APIs:</td>";
|
||||
coverage_report << six_tabs << "<td class=\""<< font_class << "\">" <<
|
||||
std::fixed << std::setprecision(2) << basic_stats.tests_coverage_percentage << "%</td>";
|
||||
coverage_report
|
||||
<< six_tabs
|
||||
<< "<td class=\"headerItem\">Test coverage by implemented tests for the HIP APIs:</td>";
|
||||
coverage_report << six_tabs << "<td class=\"" << font_class << "\">" << std::fixed
|
||||
<< std::setprecision(2) << basic_stats.tests_coverage_percentage << "%</td>";
|
||||
coverage_report << six_tabs << "<td></td>";
|
||||
coverage_report << five_tabs << "</tr>";
|
||||
|
||||
coverage_report << five_tabs << "<tr><td><img src=\"resources/glass.png\" width=3 height=3></td></tr>";
|
||||
|
||||
coverage_report << five_tabs
|
||||
<< "<tr><td><img src=\"resources/glass.png\" width=3 height=3></td></tr>";
|
||||
coverage_report << four_tabs << "</table>";
|
||||
coverage_report << three_tabs << "</td>";
|
||||
coverage_report << two_tabs << "</tr>";
|
||||
|
||||
coverage_report << two_tabs << "<tr><td class=\"ruler\"><img src=\"resources/glass.png\" width=3 height=3></td></tr>\n";
|
||||
coverage_report
|
||||
<< two_tabs
|
||||
<< "<tr><td class=\"ruler\"><img src=\"resources/glass.png\" width=3 height=3></td></tr>\n";
|
||||
coverage_report << one_tab << "</table>";
|
||||
|
||||
// Add info about HIP API Groups.
|
||||
@@ -254,11 +296,17 @@ void generateHTMLReportFiles(std::vector<HipAPI>& hip_apis, std::vector<HipAPIGr
|
||||
Create an HTML page for each API Group for more detailed information, as they are
|
||||
used as hyperlinks from the main HTML page.
|
||||
*/
|
||||
for (auto const& hip_api_group: hip_api_groups) {
|
||||
for (auto const& hip_api_group : hip_api_groups) {
|
||||
if (hip_api_group.getTotalNumberOfAPIs() == 0) {
|
||||
std::cout << "[SKIP_FROM_COV] Couldn't detect any valid HIP API within module "
|
||||
<< hip_api_group.getName() << " hence skipping its HTML generation" << std::endl;
|
||||
continue;
|
||||
}
|
||||
coverage_report << hip_api_group.getBasicStatsHTML();
|
||||
|
||||
std::fstream coverage_module_report;
|
||||
std::string report_module_file_name{test_modules_directory + "/" + hip_api_group.getName() + ".html"};
|
||||
std::string report_module_file_name{test_modules_directory + "/" + hip_api_group.getName() +
|
||||
".html"};
|
||||
coverage_module_report.open(report_module_file_name, std::ios::out);
|
||||
coverage_module_report << hip_api_group.createHTMLReport();
|
||||
coverage_module_report.close();
|
||||
@@ -266,14 +314,20 @@ void generateHTMLReportFiles(std::vector<HipAPI>& hip_apis, std::vector<HipAPIGr
|
||||
|
||||
coverage_report << two_tabs << "<tr>";
|
||||
coverage_report << three_tabs << "<td></td>";
|
||||
coverage_report << three_tabs << "<td class=\"headerCovTableEntry\">" << basic_stats.total_number_of_apis << "</td>";
|
||||
coverage_report << three_tabs << "<td class=\"headerCovTableEntry\">" << basic_stats.total_number_of_api_calls << "</td>";
|
||||
coverage_report << three_tabs << "<td class=\"headerCovTableEntry\">" << basic_stats.total_number_of_test_cases << "</td>";
|
||||
coverage_report << three_tabs << "<td class=\"headerCovTableEntry\">" << basic_stats.number_of_called_apis << "</td>";
|
||||
coverage_report << three_tabs << "<td class=\"headerCovTableEntry\">" << basic_stats.number_of_not_called_apis << "</td>";
|
||||
coverage_report << three_tabs << "<td class=\"headerCovTableEntry\">" << basic_stats.number_of_deprecated_apis << "</td>";
|
||||
coverage_report << three_tabs << "<td class=\"headerCovTableEntry\">" <<
|
||||
std::fixed << std::setprecision(2) << basic_stats.tests_coverage_percentage << "%</td>";
|
||||
coverage_report << three_tabs << "<td class=\"headerCovTableEntry\">"
|
||||
<< basic_stats.total_number_of_apis << "</td>";
|
||||
coverage_report << three_tabs << "<td class=\"headerCovTableEntry\">"
|
||||
<< basic_stats.total_number_of_api_calls << "</td>";
|
||||
coverage_report << three_tabs << "<td class=\"headerCovTableEntry\">"
|
||||
<< basic_stats.total_number_of_test_cases << "</td>";
|
||||
coverage_report << three_tabs << "<td class=\"headerCovTableEntry\">"
|
||||
<< basic_stats.number_of_called_apis << "</td>";
|
||||
coverage_report << three_tabs << "<td class=\"headerCovTableEntry\">"
|
||||
<< basic_stats.number_of_not_called_apis << "</td>";
|
||||
coverage_report << three_tabs << "<td class=\"headerCovTableEntry\">"
|
||||
<< basic_stats.number_of_deprecated_apis << "</td>";
|
||||
coverage_report << three_tabs << "<td class=\"headerCovTableEntry\">" << std::fixed
|
||||
<< std::setprecision(2) << basic_stats.tests_coverage_percentage << "%</td>";
|
||||
coverage_report << three_tabs << "<td></td>";
|
||||
coverage_report << two_tabs << "</tr>";
|
||||
|
||||
@@ -282,7 +336,57 @@ void generateHTMLReportFiles(std::vector<HipAPI>& hip_apis, std::vector<HipAPIGr
|
||||
coverage_report << one_tab << "<br>";
|
||||
|
||||
coverage_report << one_tab << "<table width=\"100%\" border=0 cellspacing=0 cellpadding=0>";
|
||||
coverage_report << two_tabs << "<tr><td class=\"ruler\"><img src=\"resources/glass.png\" width=3 height=3></td></tr>";
|
||||
coverage_report
|
||||
<< two_tabs
|
||||
<< "<tr><td class=\"ruler\"><img src=\"resources/glass.png\" width=3 height=3></td></tr>";
|
||||
coverage_report << one_tab << "</table>";
|
||||
coverage_report << one_tab << "<br>";
|
||||
|
||||
coverage_report << one_tab << "<center>";
|
||||
coverage_report << one_tab << "<table width=\"30%\" cellpadding=1 cellspacing=1 border=0>";
|
||||
coverage_report << two_tabs << "<tr>";
|
||||
coverage_report << three_tabs << "<td width=\"3%\"></td>";
|
||||
coverage_report << three_tabs << "<td width=\"97%\"></td>";
|
||||
coverage_report << two_tabs << "</tr>";
|
||||
|
||||
coverage_report << two_tabs << "<tr>";
|
||||
coverage_report << three_tabs << "<td class=\"tableHead\" colspan=2>Color legend</td>";
|
||||
coverage_report << two_tabs << "</tr>";
|
||||
|
||||
coverage_report << two_tabs << "<tr>";
|
||||
coverage_report << three_tabs << "<td class=\"coverDeprecated\"></td>";
|
||||
coverage_report << three_tabs << "<td class=\"coverFile\">Module is deprecated</td>";
|
||||
coverage_report << two_tabs << "</tr>";
|
||||
|
||||
coverage_report << two_tabs << "<tr>";
|
||||
coverage_report << three_tabs << "<td class=\"coverNumLo\"></td>";
|
||||
coverage_report
|
||||
<< three_tabs
|
||||
<< "<td class=\"coverFile\">Percentage of called APIs within a module is less than 40%</td>";
|
||||
coverage_report << two_tabs << "</tr>";
|
||||
|
||||
coverage_report << two_tabs << "<tr>";
|
||||
coverage_report << three_tabs << "<td class=\"coverNumMed\"></td>";
|
||||
coverage_report << three_tabs
|
||||
<< "<td class=\"coverFile\">Percentage of called APIs within a module is between "
|
||||
"40% and 80%</td>";
|
||||
coverage_report << two_tabs << "</tr>";
|
||||
|
||||
coverage_report << two_tabs << "<tr>";
|
||||
coverage_report << three_tabs << "<td class=\"coverNumHi\"></td>";
|
||||
coverage_report << three_tabs
|
||||
<< "<td class=\"coverFile\">Percentage of called APIs within a module is larger "
|
||||
"than 80%</td>";
|
||||
coverage_report << two_tabs << "</tr>";
|
||||
|
||||
coverage_report << one_tab << "</table>";
|
||||
coverage_report << one_tab << "</center>";
|
||||
coverage_report << one_tab << "<br>";
|
||||
|
||||
coverage_report << one_tab << "<table width=\"100%\" border=0 cellspacing=0 cellpadding=0>";
|
||||
coverage_report
|
||||
<< two_tabs
|
||||
<< "<tr><td class=\"ruler\"><img src=\"resources/glass.png\" width=3 height=3></td></tr>";
|
||||
|
||||
time_t now{time(nullptr)};
|
||||
std::string date{asctime(gmtime(&now))};
|
||||
@@ -295,7 +399,7 @@ void generateHTMLReportFiles(std::vector<HipAPI>& hip_apis, std::vector<HipAPIGr
|
||||
coverage_report.close();
|
||||
|
||||
// Create HTML report for each API, as they are used as hyperlinks from Groups HTML.
|
||||
for (auto const& hip_api: hip_apis) {
|
||||
for (auto const& hip_api : hip_apis) {
|
||||
std::fstream coverage_api_report;
|
||||
std::string report_api_file_name{test_apis_directory + "/" + hip_api.getName() + ".html"};
|
||||
coverage_api_report.open(report_api_file_name, std::ios::out);
|
||||
@@ -303,5 +407,6 @@ void generateHTMLReportFiles(std::vector<HipAPI>& hip_apis, std::vector<HipAPIGr
|
||||
coverage_api_report.close();
|
||||
}
|
||||
|
||||
std::cout << "Generated HTML report file " << findAbsolutePathOfFile(report_file_name) << std::endl;
|
||||
std::cout << "Generated HTML report file " << findAbsolutePathOfFile(report_file_name)
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,9 @@ class BasicAPIStats {
|
||||
float getMediumCoverageLimit() const;
|
||||
};
|
||||
|
||||
void generateXMLReportFiles(std::vector<HipAPI>& hip_apis, std::vector<HipAPIGroup>& hip_api_groups);
|
||||
void generateHTMLReportFiles(std::vector<HipAPI>& hip_apis, std::vector<HipAPIGroup>& hip_api_groups,
|
||||
std::string tests_root_directory, std::string hipApiHeaderFile, std::string hip_rtc_header_file);
|
||||
void generateXMLReportFiles(std::vector<HipAPI>& hip_apis,
|
||||
std::vector<HipAPIGroup>& hip_api_groups);
|
||||
void generateHTMLReportFiles(std::vector<HipAPI>& hip_apis,
|
||||
std::vector<HipAPIGroup>& hip_api_groups,
|
||||
std::string tests_root_directory, std::string hipApiHeaderFile,
|
||||
std::string hip_rtc_header_file);
|
||||
|
||||
Ссылка в новой задаче
Block a user