Revert "Revert "Merge branch 'amd-master-next' into amd-npi-next""
This reverts commit28b17d3dbd. Reason for revert: <INSERT REASONING HERE> Change-Id: I92ceb171e31026ed1864704cef2fc1497b883ef9 [ROCm/hip commit:ad2d55c144]
这个提交包含在:
1 父节点
28b17d3dbd
当前提交
e4caaa2a77
111 个文件已更改
+6800
-753
没有与搜索条件相匹配的文件
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
Copyright (c) 2020 - 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.
|
||||
*/
|
||||
|
||||
/* HIT_START
|
||||
* BUILD: %t %s ../../test_common.cpp
|
||||
* TEST: %t
|
||||
* HIT_END
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <semaphore.h>
|
||||
#include <unistd.h>
|
||||
#include "test_common.h"
|
||||
|
||||
#ifdef __linux__
|
||||
sem_t *sem_ob1 = NULL, *sem_ob2 = NULL;
|
||||
typedef struct mem_handle {
|
||||
int device;
|
||||
hipIpcMemHandle_t memHandle;
|
||||
bool IfTestPassed;
|
||||
} hip_ipc_t;
|
||||
|
||||
class IpcMemHandleTest {
|
||||
public:
|
||||
bool InitFlag = true;
|
||||
hip_ipc_t *shrd_mem = NULL;
|
||||
pid_t pid;
|
||||
size_t N = 1024;
|
||||
size_t Nbytes = N * sizeof(int);
|
||||
int *A_d = NULL, out = 0;
|
||||
int *A_h, *C_h;
|
||||
int Num_devices = 0, Data_mismatch, CanAccessPeer = 0;
|
||||
int *Ad1 = NULL, *Ad2 = NULL;
|
||||
IpcMemHandleTest();
|
||||
bool Test();
|
||||
~IpcMemHandleTest();
|
||||
};
|
||||
|
||||
|
||||
bool IpcMemHandleTest::Test() {
|
||||
if (InitFlag == false) {
|
||||
// Abort the test if the initialization fails
|
||||
printf("Resource initialization failed. Hence test skipped!");
|
||||
return false;
|
||||
}
|
||||
pid = fork();
|
||||
if (pid != 0) {
|
||||
// Parent process
|
||||
HIPCHECK(hipGetDeviceCount(&Num_devices));
|
||||
for (int i = 0; i < Num_devices; ++i) {
|
||||
if (shrd_mem->IfTestPassed == true) {
|
||||
HIPCHECK(hipSetDevice(i));
|
||||
HIPCHECK(hipMalloc(&A_d, Nbytes));
|
||||
HIPCHECK(hipIpcGetMemHandle((hipIpcMemHandle_t *) &shrd_mem->memHandle,
|
||||
A_d));
|
||||
HIPCHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
|
||||
shrd_mem->device = i;
|
||||
if ((out=sem_post(sem_ob1)) == -1) {
|
||||
// Need to use inline function to release resources.
|
||||
shrd_mem->IfTestPassed = false;
|
||||
failed("sem_post() call failed in parent process.");
|
||||
}
|
||||
if ((out=sem_wait(sem_ob2)) == -1) {
|
||||
shrd_mem->IfTestPassed = false;
|
||||
failed("sem_wait() call failed in parent process.");
|
||||
}
|
||||
HIPCHECK(hipFree(A_d));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Child process
|
||||
HIPCHECK(hipGetDeviceCount(&Num_devices));
|
||||
for (int j = 0; j < Num_devices; ++j) {
|
||||
if ((out=sem_wait(sem_ob1)) == -1) {
|
||||
shrd_mem->IfTestPassed = false;
|
||||
printf("sem_wait() call failed in child process.");
|
||||
if ((out=sem_post(sem_ob2)) == -1) {
|
||||
printf("sem_post() call on sem_ob2 failed");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < Num_devices; ++i) {
|
||||
Data_mismatch = 0;
|
||||
HIPCHECK(hipSetDevice(i));
|
||||
HIPCHECK(hipMalloc(&Ad2, Nbytes));
|
||||
HIPCHECK(hipIpcOpenMemHandle((void **) &Ad1, shrd_mem->memHandle,
|
||||
hipIpcMemLazyEnablePeerAccess));
|
||||
HIPCHECK(hipDeviceCanAccessPeer(&CanAccessPeer, i, shrd_mem->device));
|
||||
if (CanAccessPeer == 1) {
|
||||
HIPCHECK(hipMemcpy(Ad2, Ad1, Nbytes, hipMemcpyDeviceToDevice));
|
||||
HIPCHECK(hipMemcpy(C_h, Ad2, Nbytes, hipMemcpyDeviceToDevice));
|
||||
for (int i = 0; i < N; ++i) {
|
||||
if (C_h[i] != 123)
|
||||
Data_mismatch++;
|
||||
}
|
||||
if (Data_mismatch != 0) {
|
||||
printf("Data mismatch found when data copied from Ipc memhandle");
|
||||
printf(" to Device: %d\n", i);
|
||||
shrd_mem->IfTestPassed = false;
|
||||
}
|
||||
memset(reinterpret_cast<void*>(C_h), 0, Nbytes);
|
||||
// Checking if the data obtained from Ipc shared memory is consistent
|
||||
HIPCHECK(hipMemcpy(C_h, Ad1, Nbytes, hipMemcpyDeviceToHost));
|
||||
for (int i = 0; i < N; ++i) {
|
||||
if (C_h[i] != 123)
|
||||
Data_mismatch++;
|
||||
}
|
||||
if (Data_mismatch != 0) {
|
||||
printf("Data mismatch found when data copied from Ipc memhandle");
|
||||
printf(" Host.\n");
|
||||
shrd_mem->IfTestPassed = false;
|
||||
}
|
||||
}
|
||||
HIPCHECK(hipIpcCloseMemHandle(reinterpret_cast<void*>(Ad1)));
|
||||
}
|
||||
HIPCHECK(hipFree(Ad2));
|
||||
if ((out=sem_post(sem_ob2)) == -1) {
|
||||
shrd_mem->IfTestPassed = false;
|
||||
printf("sem_post() call on sem_ob2 failed");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ((out = sem_unlink("/my-sem-object1")) == -1) {
|
||||
printf("sem_unlink() call on /my-sem-object1 failed");
|
||||
}
|
||||
if ((out = sem_unlink("/my-sem-object2")) == -1) {
|
||||
printf("sem_unlink() call on /my-sem-object2 failed");
|
||||
}
|
||||
int status;
|
||||
waitpid(pid, &status, 0);
|
||||
if (shrd_mem->IfTestPassed == false) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
IpcMemHandleTest::IpcMemHandleTest() {
|
||||
std::string cmd_line = "rm -rf /dev/shm/sem.my-sem-object*";
|
||||
int res = system(cmd_line.c_str());
|
||||
if (res == -1) {
|
||||
InitFlag = false;
|
||||
printf("System call to remove existing shared objects failed!");
|
||||
}
|
||||
int out;
|
||||
if ((sem_ob1 = sem_open ("/my-sem-object1", O_CREAT|O_EXCL, 0660, 0)) ==
|
||||
SEM_FAILED) {
|
||||
InitFlag = false;
|
||||
printf("Initialization of 1st semaphore object failed");
|
||||
}
|
||||
if ((sem_ob2 = sem_open ("/my-sem-object2", O_CREAT|O_EXCL, 0660, 0)) ==
|
||||
SEM_FAILED) {
|
||||
InitFlag = false;
|
||||
printf("Initialization of 2nd semaphore object failed");
|
||||
}
|
||||
|
||||
shrd_mem = reinterpret_cast<hip_ipc_t *>(mmap(NULL, sizeof(hip_ipc_t),
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED | MAP_ANONYMOUS,
|
||||
0, 0));
|
||||
if (shrd_mem == NULL) {
|
||||
InitFlag = false;
|
||||
printf("mmap() call failed!");
|
||||
}
|
||||
shrd_mem->IfTestPassed = true;
|
||||
A_h = reinterpret_cast<int*>(malloc(Nbytes));
|
||||
C_h = reinterpret_cast<int*>(malloc(Nbytes));
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
A_h[i] = 123;
|
||||
}
|
||||
}
|
||||
|
||||
IpcMemHandleTest::~IpcMemHandleTest() {
|
||||
munmap(shrd_mem, sizeof(hip_ipc_t));
|
||||
HIPCHECK(hipFree((A_d)));
|
||||
free(A_h);
|
||||
free(C_h);
|
||||
HIPCHECK(hipFree((Ad1)));
|
||||
HIPCHECK(hipFree((Ad2)));
|
||||
}
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
bool IfTestPassed = true;
|
||||
// The following program spawns a child process and does the following
|
||||
// Parent iterate through each device, create memory -- create hipIpcMemhandle
|
||||
// stores the mem handle in mmaped memory, release the child using sem_post()
|
||||
// and wait for child to release itself(parent process)
|
||||
// child process:
|
||||
// Child process get the ipc mem handle using hipIpcOpenMemHandle
|
||||
// Iterate through all the available gpus and do Device to Device copies
|
||||
// and check for data consistencies and close the hipIpcCloseMemHandle
|
||||
// release the parent and wait for parent to release itself(child)
|
||||
#ifdef __linux__
|
||||
IpcMemHandleTest obj;
|
||||
IfTestPassed = obj.Test();
|
||||
#else
|
||||
printf("This is not a Linux platform. Hence Skipping the test!\n");
|
||||
IfTestPassed = true;
|
||||
#endif
|
||||
if (IfTestPassed == false) {
|
||||
failed("");
|
||||
}
|
||||
passed();
|
||||
}
|
||||
@@ -0,0 +1,487 @@
|
||||
/*
|
||||
Copyright (c) 2020-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 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
Testcase Scenarios :
|
||||
|
||||
(TestCase 1)::
|
||||
1) Test hipMalloc() api passing zero size and confirming *ptr returning
|
||||
nullptr. Also pass nullptr to hipFree() api.
|
||||
2) Pass maximum value of size_t for hipMalloc() api and make sure appropriate
|
||||
error is returned.
|
||||
3) Check for hipMalloc() error code, passing invalid/null pointer.
|
||||
|
||||
(TestCase 2)::
|
||||
4) Regress hipMalloc()/hipFree() in loop for bigger chunk of allocation
|
||||
with adequate number of iterations and later test for kernel execution on
|
||||
default gpu.
|
||||
5) Regress hipMalloc()/hipFree() in loop while allocating smaller chunks
|
||||
keeping maximum number of iterations and then run kernel code on default
|
||||
gpu, perfom data validation.
|
||||
|
||||
(TestCase 3)::
|
||||
6) Check hipMalloc() api adaptability when app creates small chunks of memory
|
||||
continuously, stores it for later use and then frees it at later point
|
||||
of time.
|
||||
|
||||
(TestCase 4)::
|
||||
7) Run hipMalloc() api/kernel code on same gpu parallely from parent and child
|
||||
processes, validate the results.
|
||||
|
||||
(TestCase 5)::
|
||||
8) Execute hipMalloc() api simultaneously on all the gpus by spawning multiple
|
||||
child processes. Validate buffers allocated after running kernel code.
|
||||
|
||||
(TestCase 6)::
|
||||
9) Multithread Scenario : Exercise hipMalloc() api parellely on all gpus from
|
||||
multiple threads and regress the api.
|
||||
|
||||
(TestCases 2, 3, 4, 5, 6)::
|
||||
10) Validate memory usage with hipMemGetInfo() while regressing hipMalloc()
|
||||
api. Check for any possible memory leaks.
|
||||
*/
|
||||
|
||||
/* HIT_START
|
||||
* BUILD: %t %s ../../test_common.cpp NVCC_OPTIONS --std=c++11
|
||||
* TEST_NAMED: %t hipMalloc_ArgValidation --tests 1
|
||||
* TEST_NAMED: %t hipMalloc_LoopRegression_AllocFreeCycle --tests 2
|
||||
* TEST_NAMED: %t hipMalloc_LoopRegression_AllocPool --tests 3
|
||||
* TEST_NAMED: %t hipMallocChild_Concurrency_DefaultGpu --tests 4
|
||||
* TEST_NAMED: %t hipMallocChild_Concurrency_MultiGpu --tests 5
|
||||
* TEST_NAMED: %t hipMalloc_MultiThreaded_MultiGpu --tests 6
|
||||
* HIT_END
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <atomic>
|
||||
|
||||
#include "test_common.h"
|
||||
|
||||
/* Max alloc/free iterations for bigger chunks */
|
||||
#define MAX_ALLOCFREE_BC (10000)
|
||||
|
||||
/* Buffer size for alloc/free cycles */
|
||||
#define BUFF_SIZE_AF (5*1024*1024)
|
||||
|
||||
/* Max alloc/free iterations for smaller chunks */
|
||||
#define MAX_ALLOCFREE_SC (5000000)
|
||||
|
||||
/* Max alloc and pool iterations (TBD) */
|
||||
#define MAX_ALLOCPOOL_ITER (2000000)
|
||||
|
||||
/**
|
||||
* Validates data consitency on supplied gpu
|
||||
*/
|
||||
bool validateMemoryOnGPU(int gpu) {
|
||||
size_t Nbytes = N * sizeof(int);
|
||||
int *A_d, *B_d, *C_d;
|
||||
int *A_h, *B_h, *C_h;
|
||||
size_t prevAvl, prevTot, curAvl, curTot;
|
||||
bool TestPassed = true;
|
||||
|
||||
HIPCHECK(hipSetDevice(gpu));
|
||||
HIPCHECK(hipMemGetInfo(&prevAvl, &prevTot));
|
||||
HipTest::initArrays(&A_d, &B_d, &C_d, &A_h, &B_h, &C_h, N, false);
|
||||
|
||||
unsigned blocks = HipTest::setNumBlocks(blocksPerCU, threadsPerBlock, N);
|
||||
|
||||
HIPCHECK(hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
|
||||
HIPCHECK(hipMemcpy(B_d, B_h, Nbytes, hipMemcpyHostToDevice));
|
||||
|
||||
hipLaunchKernelGGL(HipTest::vectorADD, dim3(blocks), dim3(threadsPerBlock),
|
||||
0, 0, static_cast<const int*>(A_d),
|
||||
static_cast<const int*>(B_d), C_d, N);
|
||||
|
||||
HIPCHECK(hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
|
||||
|
||||
if (!HipTest::checkVectorADD(A_h, B_h, C_h, N)) {
|
||||
printf("Validation PASSED for gpu %d from pid %d\n", gpu, getpid());
|
||||
} else {
|
||||
printf("%s : Validation FAILED for gpu %d from pid %d\n",
|
||||
__func__, gpu, getpid());
|
||||
TestPassed &= false;
|
||||
}
|
||||
|
||||
HipTest::freeArrays(A_d, B_d, C_d, A_h, B_h, C_h, false);
|
||||
HIPCHECK(hipMemGetInfo(&curAvl, &curTot));
|
||||
|
||||
if ((prevAvl != curAvl) || (prevTot != curTot)) {
|
||||
printf("%s : Memory allocation mismatch observed."
|
||||
"Possible memory leak.", __func__);
|
||||
TestPassed &= false;
|
||||
}
|
||||
|
||||
return TestPassed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches Gpu device count
|
||||
*/
|
||||
void getDeviceCount(int *pdevCnt) {
|
||||
#ifdef __linux__
|
||||
int fd[2], val = 0;
|
||||
pid_t childpid;
|
||||
|
||||
// create pipe descriptors
|
||||
pipe(fd);
|
||||
|
||||
// disable visible_devices env from shell
|
||||
unsetenv("ROCR_VISIBLE_DEVICES");
|
||||
unsetenv("HIP_VISIBLE_DEVICES");
|
||||
|
||||
childpid = fork();
|
||||
|
||||
if (childpid > 0) { // Parent
|
||||
close(fd[1]);
|
||||
// parent will wait to read the device cnt
|
||||
read(fd[0], &val, sizeof(val));
|
||||
|
||||
// close the read-descriptor
|
||||
close(fd[0]);
|
||||
|
||||
// wait for child exit
|
||||
wait(NULL);
|
||||
|
||||
*pdevCnt = val;
|
||||
} else if (!childpid) { // Child
|
||||
int devCnt = 1;
|
||||
// writing only, no need for read-descriptor
|
||||
close(fd[0]);
|
||||
|
||||
HIPCHECK(hipGetDeviceCount(&devCnt));
|
||||
// send the value on the write-descriptor:
|
||||
write(fd[1], &devCnt, sizeof(devCnt));
|
||||
|
||||
// close the write descriptor:
|
||||
close(fd[1]);
|
||||
exit(0);
|
||||
} else { // failure
|
||||
*pdevCnt = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
HIPCHECK(hipGetDeviceCount(pdevCnt));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Regress memory allocation and free in loop
|
||||
*/
|
||||
bool regressAllocInLoop(int gpu) {
|
||||
bool TestPassed = true;
|
||||
size_t tot, avail, ptot, pavail;
|
||||
int i = 0;
|
||||
int *ptr;
|
||||
|
||||
HIPCHECK(hipSetDevice(gpu));
|
||||
|
||||
// Exercise allocation in loop with bigger chunks
|
||||
for (i = 0; i < MAX_ALLOCFREE_BC; i++) {
|
||||
size_t numBytes = BUFF_SIZE_AF;
|
||||
|
||||
HIPCHECK(hipMemGetInfo(&pavail, &ptot));
|
||||
HIPCHECK(hipMalloc(&ptr, numBytes));
|
||||
HIPCHECK(hipMemGetInfo(&avail, &tot));
|
||||
|
||||
if (pavail-avail != numBytes) {
|
||||
printf("LoopAllocation : Memory allocation of %6.2fMB"
|
||||
"not matching with hipMemGetInfo - FAIL\n",
|
||||
numBytes/(1024.0*1024.0));
|
||||
TestPassed &= false;
|
||||
HIPCHECK(hipFree(ptr));
|
||||
break;
|
||||
}
|
||||
|
||||
HIPCHECK(hipFree(ptr));
|
||||
}
|
||||
|
||||
// Exercise allocation in loop with smaller chunks and max iters
|
||||
HIPCHECK(hipMemGetInfo(&pavail, &ptot));
|
||||
|
||||
for (i = 0; i < MAX_ALLOCFREE_SC; i++) {
|
||||
size_t numBytes = 16;
|
||||
|
||||
HIPCHECK(hipMalloc(&ptr, numBytes));
|
||||
|
||||
HIPCHECK(hipFree(ptr));
|
||||
}
|
||||
|
||||
HIPCHECK(hipMemGetInfo(&avail, &tot));
|
||||
|
||||
if ((pavail != avail) || (ptot != tot)) {
|
||||
printf("LoopAllocation : Memory allocation mismatch observed."
|
||||
"Possible memory leak.");
|
||||
TestPassed &= false;
|
||||
}
|
||||
|
||||
return TestPassed;
|
||||
}
|
||||
|
||||
/*
|
||||
* Thread func to regress alloc and check data consistency
|
||||
*/
|
||||
|
||||
std::atomic<bool> g_thTestPassed(true);
|
||||
|
||||
void threadFunc(int gpu) {
|
||||
g_thTestPassed = g_thTestPassed & regressAllocInLoop(gpu);
|
||||
g_thTestPassed = g_thTestPassed & validateMemoryOnGPU(gpu);
|
||||
|
||||
printf("thread execution status on gpu(%d) : %d\n", gpu, g_thTestPassed.load());
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
HipTest::parseStandardArguments(argc, argv, true);
|
||||
|
||||
if (p_tests == 1) { // Arg validation
|
||||
// Test hipMalloc for zero size
|
||||
bool TestPassed = true;
|
||||
int *ptr;
|
||||
|
||||
HIPCHECK(hipMalloc(&ptr, 0));
|
||||
|
||||
// ptr expected to be reset to null ptr
|
||||
if (ptr) {
|
||||
printf("ArgValidation : Failed in zero size test\n");
|
||||
TestPassed &= false;
|
||||
}
|
||||
|
||||
// Free null ptr
|
||||
HIPCHECK(hipFree(ptr));
|
||||
|
||||
// Test hipMalloc for invalid arguments
|
||||
hipError_t ret;
|
||||
|
||||
if ((ret = hipMalloc(NULL, 100)) != hipErrorInvalidValue) {
|
||||
printf("ArgValidation : Inappropritate error value returned"
|
||||
" for invalid argument. Error: '%s'(%d)\n",
|
||||
hipGetErrorString(ret), ret);
|
||||
TestPassed &= false;
|
||||
}
|
||||
|
||||
// Test hipMalloc for Maximum value of size_t
|
||||
if ((ret = hipMalloc(&ptr, std::numeric_limits<std::size_t>::max()))
|
||||
!= hipErrorMemoryAllocation) {
|
||||
printf("ArgValidation : Invalid error returned for max size_t."
|
||||
" Error: '%s'(%d)\n", hipGetErrorString(ret), ret);
|
||||
TestPassed &= false;
|
||||
}
|
||||
|
||||
if (TestPassed) {
|
||||
passed();
|
||||
} else {
|
||||
failed("hipMalloc ArgumentValidation Failure!");
|
||||
}
|
||||
|
||||
} else if (p_tests == 2) { // Loop Regression Alloc/Free Cycle
|
||||
bool TestPassed = true;
|
||||
|
||||
TestPassed &= regressAllocInLoop(0);
|
||||
TestPassed &= validateMemoryOnGPU(0);
|
||||
|
||||
if (TestPassed) {
|
||||
passed();
|
||||
} else {
|
||||
failed("hipMalloc_LoopRegression_AllocFreeCycle Failure!");
|
||||
}
|
||||
|
||||
} else if (p_tests == 3) { // Loop Regression Alloc and Pool
|
||||
size_t avail, tot, pavail, ptot;
|
||||
bool TestPassed = true;
|
||||
hipError_t err;
|
||||
int *ptr;
|
||||
|
||||
std::vector<int *> ptrlist;
|
||||
|
||||
HIPCHECK(hipMemGetInfo(&pavail, &ptot));
|
||||
|
||||
// Allocate small chunks of memory million times
|
||||
for (int i = 0; i < MAX_ALLOCPOOL_ITER; i++) { // Iterations TBD
|
||||
if ((err = hipMalloc(&ptr, 10)) != hipSuccess) {
|
||||
HIPCHECK(hipMemGetInfo(&avail, &tot));
|
||||
|
||||
printf("Loop regression pool allocation failure. "
|
||||
"Total gpu memory : %6.2fMB, Free memory %6.2fMB iter %d error '%s'\n",
|
||||
tot/(1024.0*1024.0), avail/(1024.0*1024.0), i, hipGetErrorString(err));
|
||||
|
||||
TestPassed &= false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Store pointers allocated to emulate memory pool of app
|
||||
ptrlist.push_back(ptr);
|
||||
}
|
||||
|
||||
// Free ptrs at later point of time
|
||||
for ( auto &t : ptrlist ) {
|
||||
HIPCHECK(hipFree(t));
|
||||
}
|
||||
|
||||
HIPCHECK(hipMemGetInfo(&avail, &tot));
|
||||
|
||||
TestPassed &= validateMemoryOnGPU(0);
|
||||
|
||||
if ((pavail != avail) || (ptot != tot)) {
|
||||
printf("%s : Memory allocation mismatch observed. Possible memory leak.",
|
||||
__func__);
|
||||
TestPassed &= false;
|
||||
}
|
||||
|
||||
if (TestPassed) {
|
||||
passed();
|
||||
} else {
|
||||
failed("hipMalloc_LoopRegression_AllocPool failure!");
|
||||
}
|
||||
|
||||
} else if (p_tests == 4) {
|
||||
bool TestPassed = true;
|
||||
|
||||
#ifdef __linux__
|
||||
// Parallel execution of parent and child on gpu0
|
||||
int pid;
|
||||
|
||||
if ((pid = fork()) < 0) {
|
||||
printf("Child_Concurrency_Gpu0 : fork() returned error %d.", pid);
|
||||
TestPassed &= false;
|
||||
|
||||
} else if (!pid) { // Child process
|
||||
bool TestPassedChild = true;
|
||||
|
||||
TestPassedChild = validateMemoryOnGPU(0);
|
||||
|
||||
if (TestPassedChild) {
|
||||
exit(0); // child exit with success status
|
||||
} else {
|
||||
printf("Child_Concurrency_Gpu0 : childpid %d failed\n", getpid());
|
||||
exit(1); // child exit with failure status
|
||||
}
|
||||
|
||||
} else { // Parent process
|
||||
int exitStatus;
|
||||
TestPassed = validateMemoryOnGPU(0);
|
||||
|
||||
pid = wait(&exitStatus);
|
||||
if ( WEXITSTATUS(exitStatus) || ( pid < 0 ) )
|
||||
TestPassed &= false;
|
||||
}
|
||||
#else
|
||||
printf("Test hipMallocChild_Concurrency_DefaultGpu skipped on non-linux\n");
|
||||
#endif
|
||||
|
||||
// TC scenarios specific to linux
|
||||
// are treated as pass in windows.
|
||||
if (TestPassed) {
|
||||
passed();
|
||||
} else {
|
||||
failed("hipMallocChild_Concurrency_DefaultGpu Failed!");
|
||||
}
|
||||
|
||||
} else if (p_tests == 5) {
|
||||
bool TestPassed = true;
|
||||
#ifdef __linux__
|
||||
// Parallel execution on multiple gpus from different child processes
|
||||
int devCnt = 1, pid = 0, cumStatus = 0;
|
||||
|
||||
// Get GPU count
|
||||
getDeviceCount(&devCnt);
|
||||
|
||||
// Spawn child for each GPU
|
||||
for (int gpu = 0; gpu < devCnt; gpu++) {
|
||||
if ((pid = fork()) < 0) {
|
||||
printf("Child_Concurrency_MultiGpu : fork() returned error %d\n", pid);
|
||||
failed("Test Failed!");
|
||||
|
||||
} else if (!pid) { // Child process
|
||||
bool TestPassedChild = true;
|
||||
TestPassedChild = validateMemoryOnGPU(gpu);
|
||||
|
||||
if (TestPassedChild) {
|
||||
exit(0); // child exit with success status
|
||||
} else {
|
||||
printf("Child_Concurrency_MultiGpu : childpid %d failed\n",
|
||||
getpid());
|
||||
exit(1); // child exit with failure status
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parent shall wait for child to complete
|
||||
for (int i = 0; i < devCnt; i++) {
|
||||
int pidwait = 0, exitStatus;
|
||||
pidwait = wait(&exitStatus);
|
||||
|
||||
if (pidwait < 0) {
|
||||
TestPassed &= false;
|
||||
break;
|
||||
}
|
||||
|
||||
cumStatus |= WEXITSTATUS(exitStatus);
|
||||
}
|
||||
|
||||
// Cummulative status of all child
|
||||
if (cumStatus) {
|
||||
TestPassed &= false;
|
||||
}
|
||||
|
||||
#else
|
||||
printf("Test hipMallocChild_Concurrency_MultiGpu skipped on non-linux\n");
|
||||
#endif
|
||||
|
||||
|
||||
// TC scenarios specific to linux
|
||||
// are treated as pass in windows.
|
||||
if (TestPassed) {
|
||||
passed();
|
||||
} else {
|
||||
failed("hipMallocChild_Concurrency_MultiGpu Failed!");
|
||||
}
|
||||
|
||||
} else if (p_tests == 6) { // Multithreaded multiple gpu execution
|
||||
std::vector<std::thread> threadlist;
|
||||
int devCnt = 1;
|
||||
|
||||
// Get GPU count
|
||||
getDeviceCount(&devCnt);
|
||||
|
||||
|
||||
for (int i = 0; i < devCnt; i++) {
|
||||
threadlist.push_back(std::thread(threadFunc, i));
|
||||
}
|
||||
|
||||
for (auto &t : threadlist) {
|
||||
t.join();
|
||||
}
|
||||
|
||||
if (g_thTestPassed) {
|
||||
passed();
|
||||
} else {
|
||||
failed("hipMalloc_MultiThreaded_MultiGpu Failed!");
|
||||
}
|
||||
} else {
|
||||
failed("Didnt receive any valid option. Try options 1 to 6\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
Copyright (c) 2020 - 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.
|
||||
*/
|
||||
|
||||
/* Test 6 is disabled */
|
||||
/* HIT_START
|
||||
* BUILD: %t %s ../../test_common.cpp NVCC_OPTIONS -std=c++11
|
||||
* TEST_NAMED: %t hipMallocManaged1 --tests 1
|
||||
* TEST_NAMED: %t hipMallocManaged2 --tests 2
|
||||
* TEST_NAMED: %t hipMallocManagedNegativeTests --tests 3
|
||||
* TEST_NAMED: %t hipMallocManagedMultiChunkSingleDevice --tests 4
|
||||
* TEST_NAMED: %t hipMallocManagedMultiChunkMultiDevice --tests 5 EXCLUDE_HIP_PLATFORM nvcc
|
||||
* TEST_NAMED: %t hipMallocManagedOversubscription --tests 6 EXCLUDE_HIP_PLATFORM rocclr nvcc
|
||||
* HIT_END
|
||||
*/
|
||||
|
||||
#include <atomic>
|
||||
#include "test_common.h"
|
||||
#define N 1048576 // equals to (1024*1024)
|
||||
#define INIT_VAL 123
|
||||
|
||||
/*
|
||||
* Kernel function to perform addition operation.
|
||||
*/
|
||||
template <typename T>
|
||||
__global__ void
|
||||
vector_sum(T *Ad1, T *Ad2, size_t NUM_ELMTS) {
|
||||
size_t offset = (blockIdx.x * blockDim.x + threadIdx.x);
|
||||
size_t stride = blockDim.x * gridDim.x;
|
||||
|
||||
for (size_t i = offset; i < NUM_ELMTS; i += stride) {
|
||||
Ad2[i] = Ad1[i] + Ad1[i];
|
||||
}
|
||||
}
|
||||
|
||||
// The following Test case tests the following scenario:
|
||||
// A large chunk of hipMallocManaged() memory(Hmm) is created
|
||||
// Equal parts of Hmm is accessed on available gpus and
|
||||
// kernel is launched on acessed chunk of hmm memory
|
||||
// and checks if there are any inconsistencies or access issues
|
||||
bool MultiChunkMultiDevice(int NumDevices) {
|
||||
std::atomic<int> DataMismatch{0};
|
||||
bool IfTestPassed = true;
|
||||
int Counter = 0;
|
||||
unsigned int NUM_ELMS = (1024 * 1024);
|
||||
float *Ad[NumDevices], *Hmm = NULL, *Ah = new float[NUM_ELMS];
|
||||
hipStream_t stream[NumDevices];
|
||||
for (int Oloop = 0; Oloop < NumDevices; ++Oloop) {
|
||||
HIPCHECK(hipSetDevice(Oloop));
|
||||
HIPCHECK(hipMalloc(&Ad[Oloop], NUM_ELMS * sizeof(float)));
|
||||
HIPCHECK(hipMemset(Ad[Oloop], 0, NUM_ELMS * sizeof(float)));
|
||||
HIPCHECK(hipStreamCreate(&stream[Oloop]));
|
||||
}
|
||||
HIPCHECK(hipMallocManaged(&Hmm, (NumDevices * NUM_ELMS * sizeof(float))));
|
||||
for (int i = 0; i < NumDevices; ++i) {
|
||||
for (; Counter < ((i + 1) * NUM_ELMS); ++Counter) {
|
||||
Hmm[Counter] = INIT_VAL + i;
|
||||
}
|
||||
}
|
||||
const unsigned threadsPerBlock = 256;
|
||||
const unsigned blocks = (NUM_ELMS + 255)/256;
|
||||
for (int Klaunch = 0; Klaunch < NumDevices; ++Klaunch) {
|
||||
vector_sum<float> <<<blocks, threadsPerBlock, 0, stream[Klaunch]>>>
|
||||
(&Hmm[Klaunch * NUM_ELMS], Ad[Klaunch], NUM_ELMS);
|
||||
}
|
||||
HIPCHECK(hipDeviceSynchronize());
|
||||
for (int m = 0; m < NumDevices; ++m) {
|
||||
HIPCHECK(hipMemcpy(Ah, Ad[m], NUM_ELMS * sizeof(float),
|
||||
hipMemcpyDeviceToHost));
|
||||
for (int n = 0; n < NUM_ELMS; ++n) {
|
||||
if (Ah[n] != ((INIT_VAL + m) * 2)) {
|
||||
DataMismatch++;
|
||||
}
|
||||
}
|
||||
memset(reinterpret_cast<void*>(Ah), 0, NUM_ELMS * sizeof(float));
|
||||
}
|
||||
if (DataMismatch.load() != 0) {
|
||||
printf("MultiChunkMultiDevice: Mismatch observed!\n");
|
||||
IfTestPassed = false;
|
||||
}
|
||||
for (int i = 0; i < NumDevices; ++i) {
|
||||
HIPCHECK(hipFree(Ad[i]));
|
||||
HIPCHECK(hipStreamDestroy(stream[i]));
|
||||
}
|
||||
HIPCHECK(hipFree(Hmm));
|
||||
free(Ah);
|
||||
return IfTestPassed;
|
||||
}
|
||||
|
||||
// The following Test case tests the following scenario:
|
||||
// A large chunk of hipMallocManaged() memory(Hmm) is created
|
||||
// Equal parts of Hmm is accessed and
|
||||
// kernel is launched on acessed chunk of hmm memory
|
||||
// and checks if there are any inconsistencies or access issues
|
||||
|
||||
bool MultiChunkSingleDevice(int NumDevices) {
|
||||
std::atomic<int> DataMismatch{0};
|
||||
int Chunks = 4, Counter = 0;
|
||||
bool IfTestPassed = true;
|
||||
unsigned int NUM_ELMS = (1024 * 1024);
|
||||
float *Ad[Chunks], *Hmm = NULL, *Ah = new float[NUM_ELMS];
|
||||
hipStream_t stream[Chunks];
|
||||
for (int i = 0; i < Chunks; ++i) {
|
||||
HIPCHECK(hipMalloc(&Ad[i], NUM_ELMS * sizeof(float)));
|
||||
HIPCHECK(hipMemset(Ad[i], 0, NUM_ELMS * sizeof(float)));
|
||||
HIPCHECK(hipStreamCreate(&stream[i]));
|
||||
}
|
||||
HIPCHECK(hipMallocManaged(&Hmm, (Chunks * NUM_ELMS * sizeof(float))));
|
||||
for (int i = 0; i < Chunks; ++i) {
|
||||
for (; Counter < ((i + 1) * NUM_ELMS); ++Counter) {
|
||||
Hmm[Counter] = (INIT_VAL + i);
|
||||
}
|
||||
}
|
||||
const unsigned threadsPerBlock = 256;
|
||||
const unsigned blocks = (NUM_ELMS + 255)/256;
|
||||
for (int k = 0; k < Chunks; ++k) {
|
||||
vector_sum<float> <<<blocks, threadsPerBlock, 0, stream[k]>>>
|
||||
(&Hmm[k * NUM_ELMS], Ad[k], NUM_ELMS);
|
||||
}
|
||||
HIPCHECK(hipDeviceSynchronize());
|
||||
for (int m = 0; m < Chunks; ++m) {
|
||||
HIPCHECK(hipMemcpy(Ah, Ad[m], NUM_ELMS * sizeof(float),
|
||||
hipMemcpyDeviceToHost));
|
||||
for (int n = 0; n < NUM_ELMS; ++n) {
|
||||
if (Ah[n] != ((INIT_VAL + m) * 2)) {
|
||||
DataMismatch++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DataMismatch.load() != 0) {
|
||||
printf("MultiChunkSingleDevice: Mismatch observed!\n");
|
||||
IfTestPassed = false;
|
||||
}
|
||||
for (int i = 0; i < Chunks; ++i) {
|
||||
HIPCHECK(hipFree(Ad[i]));
|
||||
HIPCHECK(hipStreamDestroy(stream[i]));
|
||||
}
|
||||
HIPCHECK(hipFree(Hmm));
|
||||
free(Ah);
|
||||
return IfTestPassed;
|
||||
}
|
||||
|
||||
// The following tests oversubscription hipMallocManaged() api
|
||||
// Currently disabled.
|
||||
bool TestOversubscriptionMallocManaged(int NumDevices) {
|
||||
bool IfTestPassed = true;
|
||||
hipError_t err;
|
||||
void *A = NULL;
|
||||
size_t total = 0, free = 0;
|
||||
HIPCHECK(hipMemGetInfo(&free, &total));
|
||||
// ToDo: In case of HMM, memory over-subscription is allowed. Hence, relook
|
||||
// into how out of memory can be tested.
|
||||
// Demanding more mem size than available
|
||||
err = hipMallocManaged(&A, (free +1), hipMemAttachGlobal);
|
||||
if (hipErrorOutOfMemory != err) {
|
||||
printf("hipMallocManaged: Returned %s for size value > device memory\n",
|
||||
hipGetErrorString(err));
|
||||
IfTestPassed = false;
|
||||
}
|
||||
|
||||
return IfTestPassed;
|
||||
}
|
||||
|
||||
// The following test does negative testing of hipMallocManaged() api
|
||||
// by passing invalid values and check if the behavior is as expected
|
||||
bool NegativeTestsMallocManaged(int NumDevices) {
|
||||
bool IfTestPassed = true;
|
||||
hipError_t err;
|
||||
void *A = NULL;
|
||||
size_t total = 0, free = 0;
|
||||
HIPCHECK(hipMemGetInfo(&free, &total));
|
||||
|
||||
err = hipMallocManaged(NULL, 1024, hipMemAttachGlobal);
|
||||
if (hipErrorInvalidValue != err) {
|
||||
printf("hipMallocManaged: Returned %s when devPtr is null\n",
|
||||
hipGetErrorString(err));
|
||||
IfTestPassed = false;
|
||||
}
|
||||
|
||||
err = hipMallocManaged(&A, 0, hipMemAttachGlobal);
|
||||
if (hipErrorInvalidValue != err) {
|
||||
printf("hipMallocManaged: Returned %s when size is 0\n",
|
||||
hipGetErrorString(err));
|
||||
IfTestPassed = false;
|
||||
}
|
||||
|
||||
err = hipMallocManaged(NULL, 0, hipMemAttachGlobal);
|
||||
if (hipErrorInvalidValue != err) {
|
||||
printf("hipMallocManaged: Returned %s when devPtr & size is null & 0\n",
|
||||
hipGetErrorString(err));
|
||||
IfTestPassed = false;
|
||||
}
|
||||
|
||||
#ifdef __HIP_PLATFORM_HCC__
|
||||
// The flag hipMemAttachHost is currently not supported therefore
|
||||
// api should return "hipErrorInvalidValue" for now
|
||||
err = hipMallocManaged(&A, 1024, hipMemAttachHost);
|
||||
if (hipErrorInvalidValue != err) {
|
||||
printf("hipMallocManaged: Returned %s for 'hipMemAttachHost' flag\n",
|
||||
hipGetErrorString(err));
|
||||
IfTestPassed = false;
|
||||
}
|
||||
#endif // __HIP_PLATFORM_HCC__
|
||||
|
||||
err = hipMallocManaged(NULL, 0, 0);
|
||||
if (hipErrorInvalidValue != err) {
|
||||
printf("hipMallocManaged: Returned %s when params are null, 0, 0\n",
|
||||
hipGetErrorString(err));
|
||||
IfTestPassed = false;
|
||||
}
|
||||
|
||||
err = hipMallocManaged(&A, 1024, 145);
|
||||
if (hipErrorInvalidValue != err) {
|
||||
printf("hipMallocManaged: Returned %s when flag param is numerical 145\n",
|
||||
hipGetErrorString(err));
|
||||
IfTestPassed = false;
|
||||
}
|
||||
|
||||
err = hipMallocManaged(&A, -10, hipMemAttachGlobal);
|
||||
if (hipErrorOutOfMemory != err) {
|
||||
printf("hipMallocManaged: Returned %s for negative size value.\n",
|
||||
hipGetErrorString(err));
|
||||
IfTestPassed = false;
|
||||
}
|
||||
|
||||
return IfTestPassed;
|
||||
}
|
||||
|
||||
|
||||
// Allocate two pointers using hipMallocManaged(), initialize,
|
||||
// then launch kernel using these pointers directly and
|
||||
// later validate the content without using any Memcpy.
|
||||
template <typename T>
|
||||
bool TestMallocManaged2(int NumDevices) {
|
||||
bool IfTestPassed = true;
|
||||
T *Hmm1 = NULL, *Hmm2 = NULL;
|
||||
|
||||
for (int i = 0; i < NumDevices; ++i) {
|
||||
HIPCHECK(hipSetDevice(i));
|
||||
std::atomic<int> DataMismatch{0};
|
||||
HIPCHECK(hipMallocManaged(&Hmm1, N * sizeof(T)));
|
||||
HIPCHECK(hipMallocManaged(&Hmm2, N * sizeof(T)));
|
||||
for (int m = 0; m < N; ++m) {
|
||||
Hmm1[m] = m;
|
||||
Hmm2[m] = 0;
|
||||
}
|
||||
const unsigned threadsPerBlock = 256;
|
||||
const unsigned blocks = (N + 255)/256;
|
||||
// Kernel launch
|
||||
vector_sum <<<blocks, threadsPerBlock>>> (Hmm1, Hmm2, N);
|
||||
HIPCHECK(hipDeviceSynchronize());
|
||||
for (int v = 0; v < N; ++v) {
|
||||
if (Hmm2[v] != (v + v)) {
|
||||
DataMismatch++;
|
||||
}
|
||||
}
|
||||
if (DataMismatch.load() != 0) {
|
||||
IfTestPassed = false;
|
||||
}
|
||||
HIPCHECK(hipFree(Hmm1));
|
||||
HIPCHECK(hipFree(Hmm2));
|
||||
}
|
||||
return IfTestPassed;
|
||||
}
|
||||
|
||||
// In the following test, a memory is created using hipMallocManaged() by
|
||||
// setting a device and verified if it is accessible when the context is set
|
||||
// to all other devices. This include verification and Device two Device
|
||||
// transfers and kernel launch o discover if there any access issues.
|
||||
|
||||
template <typename T>
|
||||
bool TestMallocManaged1(int NumDevices) {
|
||||
std::atomic<unsigned int> DataMismatch;
|
||||
bool TestPassed = true;
|
||||
T *Ah1 = new T[N], *Ah2 = new T[N], *Ad = NULL, *Hmm = NULL;
|
||||
|
||||
for (int i =0; i < N; ++i) {
|
||||
Ah1[i] = INIT_VAL;
|
||||
Ah2[i] = 0;
|
||||
}
|
||||
for (int Oloop = 0; Oloop < NumDevices; ++Oloop) {
|
||||
DataMismatch = 0;
|
||||
HIPCHECK(hipSetDevice(Oloop));
|
||||
HIPCHECK(hipMallocManaged(&Hmm, N * sizeof(T)));
|
||||
for (int Iloop = 0; Iloop < NumDevices; ++Iloop) {
|
||||
HIPCHECK(hipSetDevice(Iloop));
|
||||
HIPCHECK(hipMalloc(&Ad, N * sizeof(T)));
|
||||
// Copy data from host to hipMallocMananged memory and verify
|
||||
HIPCHECK(hipMemcpy(Hmm, Ah1, N * sizeof(T), hipMemcpyHostToDevice));
|
||||
for (int v = 0; v < N; ++v) {
|
||||
if (Hmm[v] != INIT_VAL) {
|
||||
DataMismatch++;
|
||||
}
|
||||
}
|
||||
if (DataMismatch.load() != 0) {
|
||||
printf("Mismatch is observed with host data at device %d", Iloop);
|
||||
printf(" while hipMallocManaged memory set to the device %d\n", Oloop);
|
||||
TestPassed = false;
|
||||
DataMismatch = 0;
|
||||
}
|
||||
// Executing D2D transfer with hipMallocManaged memory and verify
|
||||
HIPCHECK(hipMemcpy(Ad, Hmm, N * sizeof(T), hipMemcpyDeviceToDevice));
|
||||
HIPCHECK(hipMemcpy(Ah2, Ad, N * sizeof(T), hipMemcpyDeviceToHost));
|
||||
for (int k = 0; k < N; ++k) {
|
||||
if (Ah2[k] != INIT_VAL) {
|
||||
DataMismatch++;
|
||||
}
|
||||
}
|
||||
if (DataMismatch.load() != 0) {
|
||||
printf("Mismatch is observed with D2D transfer at device %d\n", Iloop);
|
||||
printf(" while hipMallocManaged memory set to the device %d\n", Oloop);
|
||||
TestPassed = false;
|
||||
DataMismatch = 0;
|
||||
}
|
||||
HIPCHECK(hipMemset(Ad, 0, N * sizeof(T)));
|
||||
const unsigned threadsPerBlock = 256;
|
||||
const unsigned blocks = (N + 255)/256;
|
||||
// Launching the kernel to check if there is any access issue with
|
||||
// hipMallocManaged memory and local device's memory
|
||||
vector_sum <<<blocks, threadsPerBlock>>> (Hmm, Ad, N);
|
||||
hipDeviceSynchronize();
|
||||
HIPCHECK(hipMemcpy(Ah2, Ad, N * sizeof(T), hipMemcpyDeviceToHost));
|
||||
for (int m = 0; m < N; ++m) {
|
||||
if (Ah2[m] != 246) {
|
||||
DataMismatch++;
|
||||
}
|
||||
}
|
||||
if (DataMismatch.load() != 0) {
|
||||
printf("Data Mismatch observed after kernel lch device %d\n", Iloop);
|
||||
TestPassed = false;
|
||||
DataMismatch = 0;
|
||||
}
|
||||
HIPCHECK(hipFree(Ad));
|
||||
}
|
||||
HIPCHECK(hipFree(Hmm));
|
||||
}
|
||||
free(Ah1);
|
||||
free(Ah2);
|
||||
return TestPassed;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
HipTest::parseStandardArguments(argc, argv, true);
|
||||
|
||||
if ((p_tests <= 0) || (p_tests > 5)) {
|
||||
failed("Valid arguments are from 1 to 5");
|
||||
}
|
||||
|
||||
int NumDevices = 0;
|
||||
HIPCHECK(hipGetDeviceCount(&NumDevices));
|
||||
bool TestStatus = true, OverAllStatus = true;
|
||||
if (p_tests == 1) {
|
||||
TestStatus = TestMallocManaged1<float>(NumDevices);
|
||||
if (!TestStatus) {
|
||||
printf("Test Failed with float datatype.\n");
|
||||
OverAllStatus = false;
|
||||
}
|
||||
TestStatus = TestMallocManaged1<int>(NumDevices);
|
||||
if (!TestStatus) {
|
||||
printf("Test Failed with int datatype.\n");
|
||||
OverAllStatus = false;
|
||||
}
|
||||
TestStatus = TestMallocManaged1<unsigned char>(NumDevices);
|
||||
if (!TestStatus) {
|
||||
printf("Test Failed with unsigned char datatype.\n");
|
||||
OverAllStatus = false;
|
||||
}
|
||||
TestStatus = TestMallocManaged1<double>(NumDevices);
|
||||
if (!TestStatus) {
|
||||
printf("Test Failed with double datatype.\n");
|
||||
OverAllStatus = false;
|
||||
}
|
||||
if (!OverAllStatus) {
|
||||
failed("");
|
||||
}
|
||||
}
|
||||
if (p_tests == 2) {
|
||||
TestStatus = TestMallocManaged2<float>(NumDevices);
|
||||
if (!TestStatus) {
|
||||
failed("Test Failed with float datatype.");
|
||||
}
|
||||
}
|
||||
if (p_tests == 3) {
|
||||
TestStatus = NegativeTestsMallocManaged(NumDevices);
|
||||
if (!TestStatus) {
|
||||
failed("Negative Tests with hipMallocManaged() failed!.");
|
||||
}
|
||||
}
|
||||
if (p_tests == 4) {
|
||||
TestStatus = MultiChunkSingleDevice(NumDevices);
|
||||
if (!TestStatus) {
|
||||
failed("hipMallocManaged: MultiChunkSingleDevice test failed!");
|
||||
}
|
||||
}
|
||||
if (p_tests == 5) {
|
||||
TestStatus = MultiChunkMultiDevice(NumDevices);
|
||||
if (!TestStatus) {
|
||||
failed("hipMallocManaged: MultiChunkMultiDevice test failed!");
|
||||
}
|
||||
}
|
||||
if (p_tests == 6) {
|
||||
TestStatus = TestOversubscriptionMallocManaged(NumDevices);
|
||||
if (!TestStatus) {
|
||||
failed("hipMallocManaged: TestOversubscriptionMallocManaged failed!");
|
||||
}
|
||||
}
|
||||
passed();
|
||||
}
|
||||
@@ -75,6 +75,9 @@ int main() {
|
||||
HIPCHECK(hipFree(Z_d));
|
||||
} else {
|
||||
std::cout<<"Machine does not seem to have P2P Capabilities, Empty Pass"<<std::endl;
|
||||
if (hip_skip_tests_enabled()) {
|
||||
return hip_skip_retcode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,6 +81,9 @@ int main() {
|
||||
HIPCHECK(hipFree(Z_d));
|
||||
} else {
|
||||
std::cout<<"Machine does not seem to have P2P Capabilities, Empty Pass"<<std::endl;
|
||||
if (hip_skip_tests_enabled()) {
|
||||
return hip_skip_retcode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +77,9 @@ int main() {
|
||||
HIPCHECK(hipFree(Z_d));
|
||||
} else {
|
||||
std::cout<<"Machine does not seem to have P2P Capabilities, Empty Pass"<<std::endl;
|
||||
if (hip_skip_tests_enabled()) {
|
||||
return hip_skip_retcode();
|
||||
}
|
||||
}
|
||||
}
|
||||
passed();
|
||||
|
||||
@@ -83,6 +83,9 @@ int main() {
|
||||
HIPCHECK(hipFree(Z_d));
|
||||
} else {
|
||||
std::cout<<"Machine does not seem to have P2P Capabilities, Empty Pass"<<std::endl;
|
||||
if (hip_skip_tests_enabled()) {
|
||||
return hip_skip_retcode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* HIT_START
|
||||
* BUILD: %t %s ../../test_common.cpp
|
||||
* BUILD: %t %s ../../test_common.cpp EXCLUDE_HIP_PLATFORM nvcc
|
||||
* TEST: %t
|
||||
* HIT_END
|
||||
*/
|
||||
|
||||
@@ -24,7 +24,7 @@ THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* HIT_START
|
||||
* BUILD: %t %s ../../test_common.cpp
|
||||
* BUILD: %t %s ../../test_common.cpp NVCC_OPTIONS -std=c++11 EXCLUDE_HIP_PLATFORM nvcc
|
||||
* TEST: %t
|
||||
* HIT_END
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
// Test for hipMemset2D functionality for different width and height values
|
||||
|
||||
/* HIT_START
|
||||
* BUILD: %t %s ../../test_common.cpp NVCC_OPTIONS -std=c++11
|
||||
* BUILD: %t %s ../../test_common.cpp NVCC_OPTIONS -std=c++11 EXCLUDE_HIP_PLATFORM nvcc
|
||||
* TEST_NAMED: %t hipMemset2D-basic
|
||||
* TEST_NAMED: %t hipMemset2D-dim1 --width2D 10 --height2D 10 --memsetWidth 4 --memsetHeight 4
|
||||
* TEST_NAMED: %t hipMemset2D-dim2 --width2D 100 --height2D 100 --memsetWidth 20 --memsetHeight 40
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
// and also launch hipMemcpyAsync() api on the same stream. This test case is simulate the scenario
|
||||
// reported in SWDEV-181598.
|
||||
/* HIT_START
|
||||
* BUILD: %t %s ../../test_common.cpp NVCC_OPTIONS --std=c++11
|
||||
* BUILD: %t %s ../../test_common.cpp NVCC_OPTIONS --std=c++11 EXCLUDE_HIP_PLATFORM nvcc
|
||||
* TEST: %t
|
||||
* HIT_END
|
||||
*/
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
// and also launch hipMemcpyAsync() api. This test case is simulate the scenario
|
||||
// reported in SWDEV-181598.
|
||||
/* HIT_START
|
||||
* BUILD: %t %s ../../test_common.cpp NVCC_OPTIONS --std=c++11
|
||||
* BUILD: %t %s ../../test_common.cpp NVCC_OPTIONS --std=c++11 EXCLUDE_HIP_PLATFORM nvcc
|
||||
* TEST: %t
|
||||
* HIT_END
|
||||
*/
|
||||
|
||||
在新工单中引用
屏蔽一个用户