[HIP][HIPIFY] Remove HIPIFY related stuff due to moving of HIPIFY to a separate repo (#2002)
HIPIFY tools now are here: https://github.com/ROCm-Developer-Tools/HIPIFY
[ROCm/hip commit: 5f1420a229]
This commit is contained in:
@@ -1,151 +0,0 @@
|
||||
# -*- Python -*-
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import subprocess
|
||||
import struct
|
||||
|
||||
import lit.formats
|
||||
import lit.util
|
||||
|
||||
# Configuration file for the 'lit' test runner.
|
||||
site_cfg = lit_config.params.get('site_config', None)
|
||||
lit_config.load_config(config, site_cfg)
|
||||
|
||||
config.excludes = ['cmdparser.hpp']
|
||||
config.excludes.append('spatial_batch_norm_op.h')
|
||||
config.excludes.append('common_cudnn.h')
|
||||
|
||||
delimiter = "===============================================================";
|
||||
print(delimiter)
|
||||
print("CUDA " + config.cuda_version + " - will be used for testing")
|
||||
print("LLVM " + config.llvm_version + " - will be used for testing")
|
||||
print(platform.machine() + " - Platform architecture")
|
||||
print(platform.system() + " " + platform.release() + " - Platform OS")
|
||||
print(str(config.pointer_size * 8) + " - hipify-clang binary bitness")
|
||||
print(str(struct.calcsize("P") * 8) + " - python " + str(platform.python_version()) + " binary bitness")
|
||||
print(delimiter)
|
||||
warns = None
|
||||
if not config.cuda_dnn_root:
|
||||
config.excludes.append('cudnn_convolution_forward.cu')
|
||||
config.excludes.append('cudnn_softmax.cu')
|
||||
print("WARN: cuDNN tests are excluded due to unset CUDA_DNN_ROOT_DIR")
|
||||
warns = True
|
||||
if not config.cuda_cub_root:
|
||||
config.excludes.append('cub_01.cu')
|
||||
config.excludes.append('cub_02.cu')
|
||||
config.excludes.append('cub_03.cu')
|
||||
print("WARN: CUB tests are excluded due to unset CUDA_CUB_ROOT_DIR")
|
||||
warns = True
|
||||
if warns:
|
||||
print(delimiter)
|
||||
|
||||
if config.cuda_version_major == 7 and config.cuda_version_minor == 0:
|
||||
config.excludes.append('headers_test_09.cu')
|
||||
config.excludes.append('cudnn_convolution_forward.cu')
|
||||
if config.cuda_version_major < 8:
|
||||
config.excludes.append('cuSPARSE_02.cu')
|
||||
if config.cuda_version_major < 9:
|
||||
config.excludes.append('cuSPARSE_04.cu')
|
||||
config.excludes.append('cuSPARSE_05.cu')
|
||||
config.excludes.append('cuSPARSE_06.cu')
|
||||
config.excludes.append('cuSPARSE_07.cu')
|
||||
config.excludes.append('benchmark_curand_kernel.cpp')
|
||||
if config.cuda_version_major < 10:
|
||||
config.excludes.append('cuSPARSE_08.cu')
|
||||
config.excludes.append('cuSPARSE_09.cu')
|
||||
config.excludes.append('cuSPARSE_10.cu')
|
||||
config.excludes.append('cuSPARSE_11.cu')
|
||||
|
||||
if config.llvm_version_major < 10:
|
||||
config.excludes.append('pp_if_else_conditionals_LLVM_10.cu')
|
||||
config.excludes.append('pp_if_else_conditionals_01_LLVM_10.cu')
|
||||
|
||||
# name: The name of this test suite.
|
||||
config.name = 'hipify'
|
||||
|
||||
# suffixes: CUDA source is only supported
|
||||
config.suffixes = ['.cu','.cuh','.cpp','.c','.hpp','.h']
|
||||
|
||||
# testFormat: The test format to use to interpret tests.
|
||||
config.test_format = lit.formats.ShTest()
|
||||
|
||||
# test_source_root: The root path where tests are located.
|
||||
config.test_source_root = os.path.dirname(__file__)
|
||||
|
||||
# test_exec_root: The path where tests are located (default is the test suite root).
|
||||
#config.test_exec_root = config.test_source_root
|
||||
|
||||
# target_triple: Used by ShTest and TclTest formats for XFAIL checks.
|
||||
config.target_triple = '(unused)'
|
||||
|
||||
# available_features: Used by ShTest and TclTest formats for REQUIRES checks.
|
||||
config.available_features = []
|
||||
|
||||
obj_root = getattr(config, 'obj_root', None)
|
||||
if obj_root is not None:
|
||||
config.test_exec_root = obj_root
|
||||
|
||||
if obj_root is not None:
|
||||
llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
|
||||
if not llvm_tools_dir:
|
||||
lit_config.fatal('No LLVM tools dir set!')
|
||||
path = os.path.pathsep.join((llvm_tools_dir, config.environment['PATH']))
|
||||
config.environment['PATH'] = path
|
||||
|
||||
hipify_path = obj_root
|
||||
|
||||
clang_arguments = "-v"
|
||||
if sys.platform in ['win32']:
|
||||
run_test_ext = ".bat"
|
||||
hipify_path += "/" + config.build_type
|
||||
# CUDA SDK ROOT
|
||||
clang_arguments += " -isystem'%s'/common/inc"
|
||||
else:
|
||||
run_test_ext = ".sh"
|
||||
# CUDA SDK ROOT
|
||||
clang_arguments += " -isystem'%s'/samples/common/inc"
|
||||
if config.pointer_size == 8:
|
||||
clang_arguments += " -D__LP64__"
|
||||
|
||||
# Set max clang's CudaArch for corresponding CUDA version
|
||||
# to support maximum CUDA features in offline tests
|
||||
if config.cuda_version_major == 7:
|
||||
if config.cuda_version_minor == 5:
|
||||
clang_arguments += " --cuda-gpu-arch=sm_53"
|
||||
else:
|
||||
clang_arguments += " --cuda-gpu-arch=sm_52"
|
||||
elif config.cuda_version_major == 8:
|
||||
clang_arguments += " --cuda-gpu-arch=sm_62"
|
||||
elif config.cuda_version_major == 9:
|
||||
if config.cuda_version_minor == 2:
|
||||
clang_arguments += " --cuda-gpu-arch=sm_72"
|
||||
else:
|
||||
clang_arguments += " --cuda-gpu-arch=sm_70"
|
||||
elif config.cuda_version_major == 10:
|
||||
clang_arguments += " --cuda-gpu-arch=sm_75"
|
||||
|
||||
# cuDNN ROOT
|
||||
if config.cuda_dnn_root:
|
||||
clang_arguments += " -I'%s'/include"
|
||||
# CUB ROOT
|
||||
if config.cuda_cub_root:
|
||||
clang_arguments += " -I'%s'"
|
||||
|
||||
if config.cuda_dnn_root and config.cuda_cub_root:
|
||||
config.substitutions.append(("%clang_args", clang_arguments % (config.cuda_sdk_root, config.cuda_dnn_root, config.cuda_cub_root)))
|
||||
elif config.cuda_dnn_root:
|
||||
config.substitutions.append(("%clang_args", clang_arguments % (config.cuda_sdk_root, config.cuda_dnn_root)))
|
||||
elif config.cuda_cub_root:
|
||||
config.substitutions.append(("%clang_args", clang_arguments % (config.cuda_sdk_root, config.cuda_cub_root)))
|
||||
else:
|
||||
config.substitutions.append(("%clang_args", clang_arguments % config.cuda_sdk_root))
|
||||
|
||||
if config.llvm_version_major < 4:
|
||||
hipify_arguments = "-I'%s'/include"
|
||||
else:
|
||||
hipify_arguments = "--cuda-path='%s'"
|
||||
|
||||
config.substitutions.append(("%hipify_args", hipify_arguments % config.cuda_root))
|
||||
config.substitutions.append(("hipify", '"' + hipify_path + "/hipify-clang" + '"'))
|
||||
config.substitutions.append(("%run_test", '"' + config.test_source_root + "/run_test" + run_test_ext + '"'))
|
||||
@@ -1,38 +0,0 @@
|
||||
import sys
|
||||
import os
|
||||
|
||||
config.pointer_size = @CMAKE_SIZEOF_VOID_P@
|
||||
config.llvm_version = "@LLVM_PACKAGE_VERSION@"
|
||||
config.llvm_version_major = int("@LLVM_VERSION_MAJOR@")
|
||||
config.llvm_tools_dir = "@LLVM_TOOLS_BINARY_DIR@"
|
||||
config.obj_root = "@CMAKE_CURRENT_BINARY_DIR@"
|
||||
config.cuda_root = "@CUDA_TOOLKIT_ROOT_DIR@"
|
||||
config.cuda_dnn_root = "@CUDA_DNN_ROOT_DIR@"
|
||||
config.cuda_cub_root = "@CUDA_CUB_ROOT_DIR@"
|
||||
config.cuda_version_major = int("@CUDA_VERSION_MAJOR@")
|
||||
config.cuda_version_minor = int("@CUDA_VERSION_MINOR@")
|
||||
config.cuda_version = "@CUDA_VERSION@"
|
||||
if sys.platform in ['win32']:
|
||||
config.cuda_sdk_root = "@CUDA_SDK_ROOT_DIR@"
|
||||
if not config.cuda_sdk_root or config.cuda_sdk_root == "CUDA_SDK_ROOT_DIR-NOTFOUND":
|
||||
cuda_version = config.cuda_version
|
||||
cuda_version = cuda_version.replace('.','_')
|
||||
config.cuda_samples_root = os.environ.get('NVCUDASAMPLES' + cuda_version + '_ROOT')
|
||||
if not config.cuda_samples_root:
|
||||
lit_config.fatal('No CUDA Samples dir set! Please set CUDA_SDK_ROOT_DIR.')
|
||||
config.cuda_sdk_root = config.cuda_samples_root
|
||||
config.build_type = "@CMAKE_BUILD_TYPE@"
|
||||
if not config.build_type:
|
||||
config.build_type = "Debug"
|
||||
else:
|
||||
config.cuda_sdk_root = config.cuda_root
|
||||
|
||||
# Support substitution of the tools and libs dirs with user parameters. This is
|
||||
# used when we can't determine the tool dir at configuration time.
|
||||
try:
|
||||
config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params
|
||||
config.obj_root = config.obj_root % lit_config.params
|
||||
except KeyError:
|
||||
e = sys.exc_info()[1]
|
||||
key, = e.args
|
||||
lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
|
||||
@@ -1,21 +0,0 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
for %%i in (FileCheck.exe) do set FILE_CHECK=%%~$PATH:i
|
||||
if not defined FILE_CHECK (echo Error: FileCheck.exe not found in PATH. && exit /b 1)
|
||||
|
||||
set HIPIFY=%1
|
||||
set IN_FILE=%2
|
||||
set TMP_FILE=%3
|
||||
set CUDA_ROOT=%4
|
||||
set ROC=%5
|
||||
|
||||
set all_args=%*
|
||||
call set clang_args=%%all_args:*%6=%%
|
||||
set clang_args=%6%clang_args%
|
||||
|
||||
%HIPIFY% -o=%TMP_FILE% %IN_FILE% %CUDA_ROOT% %ROC% -- %clang_args%
|
||||
if errorlevel 1 (echo Error: hipify-clang.exe failed with exit code: %errorlevel% && exit /b %errorlevel%)
|
||||
|
||||
findstr /v /r /c:"[ ]*//[ ]*[CHECK*|RUN]" %TMP_FILE% | %FILE_CHECK% %IN_FILE%
|
||||
if errorlevel 1 (echo Error: FileCheck.exe failed with exit code: %errorlevel% && exit /b %errorlevel%)
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o errexit
|
||||
|
||||
# Run a single LIT test file in a magical way that preserves colour output, to work around
|
||||
# a known flaw in lit.
|
||||
|
||||
# Capture lit substitutions
|
||||
HIPIFY=$1
|
||||
IN_FILE=$2
|
||||
TMP_FILE=$3
|
||||
CUDA_ROOT=$4
|
||||
ROC=$5
|
||||
shift 5
|
||||
|
||||
# Remaining args are the ones to forward to clang proper.
|
||||
|
||||
$HIPIFY -o=$TMP_FILE $IN_FILE $CUDA_ROOT $ROC -- $@ && cat $TMP_FILE | sed -Ee 's|//.+|// |g' | FileCheck $IN_FILE
|
||||
@@ -1,52 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
/*
|
||||
Copyright (c) 2015-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.
|
||||
*/
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
|
||||
__global__
|
||||
void fn(float* px, float* py) {
|
||||
bool a[42];
|
||||
__shared__ double b[69];
|
||||
for (auto&& x : b) x = *py++;
|
||||
for (auto&& x : a) x = *px++ > 0.0;
|
||||
for (auto&& x : a) if (x) *--py = *--px;
|
||||
}
|
||||
|
||||
int main() {
|
||||
// CHECK: hipFuncCache_t cacheConfig;
|
||||
cudaFuncCache cacheConfig;
|
||||
void* func;
|
||||
// CHECK: hipFuncSetCacheConfig(reinterpret_cast<const void*>(func), cacheConfig);
|
||||
cudaFuncSetCacheConfig(func, cacheConfig);
|
||||
// CHECK: hipFuncAttributes attr{};
|
||||
cudaFuncAttributes attr{};
|
||||
// CHECK: auto r = hipFuncGetAttributes(&attr, reinterpret_cast<const void*>(&fn));
|
||||
auto r = cudaFuncGetAttributes(&attr, &fn);
|
||||
// CHECK: if (r != hipSuccess || attr.maxThreadsPerBlock == 0) {
|
||||
if (r != cudaSuccess || attr.maxThreadsPerBlock == 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,286 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args "-Xclang" "-fcuda-allow-variadic-functions"
|
||||
|
||||
/*
|
||||
Copyright (c) 2015-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.
|
||||
*/
|
||||
|
||||
// CHECK: #include "hip/hip_runtime.h"
|
||||
#include "cuda_runtime.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <type_traits>
|
||||
|
||||
#define EXIT_WAIVED 2
|
||||
|
||||
const char* sampleName = "hipSimpleAtomicsTest";
|
||||
|
||||
using namespace std;
|
||||
// Auto-Verification Code
|
||||
bool testResult = true;
|
||||
|
||||
bool computeGoldBitwise(...) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, typename enable_if<is_integral<T>{}>::type* = nullptr>
|
||||
bool computeGoldBitwise(T* gpuData, int len) {
|
||||
T val = 0xff;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
// 9th element should be 1
|
||||
val &= (2 * i + 7);
|
||||
}
|
||||
if (val != gpuData[8]) {
|
||||
printf("atomicAnd failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
val = 0;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
// 10th element should be 0xff
|
||||
val |= (1 << i);
|
||||
}
|
||||
if (val != gpuData[9]) {
|
||||
printf("atomicOr failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
val = 0xff;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
// 11th element should be 0xff
|
||||
val ^= i;
|
||||
}
|
||||
if (val != gpuData[10]) {
|
||||
printf("atomicXor failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool computeGold(T* gpuData, int len) {
|
||||
T val = 0;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
val += 10;
|
||||
}
|
||||
if (val != gpuData[0]) {
|
||||
printf("atomicAdd failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
val = 0;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
val -= 10;
|
||||
}
|
||||
if (val != gpuData[1]) {
|
||||
printf("atomicSub failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
for (T i = 0; i < len; ++i) {
|
||||
// third element should be a member of [0, len)
|
||||
if (i == gpuData[2]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
printf("atomicExch failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
val = -(1 << 8);
|
||||
for (T i = 0; i < len; ++i) {
|
||||
// fourth element should be len-1
|
||||
val = max(val, i);
|
||||
}
|
||||
if (val != gpuData[3]) {
|
||||
printf("atomicMax failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
val = 1 << 8;
|
||||
for (T i = 0; i < len; ++i) {
|
||||
val = min(val, i);
|
||||
}
|
||||
if (val != gpuData[4]) {
|
||||
printf("atomicMin failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
int limit = 17;
|
||||
val = 0;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
val = (val >= limit) ? 0 : val + 1;
|
||||
}
|
||||
if (val != gpuData[5]) {
|
||||
printf("atomicInc failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
limit = 137;
|
||||
val = 0;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
val = ((val == 0) || (val > limit)) ? limit : val - 1;
|
||||
}
|
||||
if (val != gpuData[6]) {
|
||||
printf("atomicDec failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
found = false;
|
||||
for (T i = 0; i < len; ++i) {
|
||||
// eighth element should be a member of [0, len)
|
||||
if (i == gpuData[7]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
printf("atomicCAS failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return computeGoldBitwise(gpuData, len);
|
||||
}
|
||||
|
||||
__device__
|
||||
void testKernelExch(...) {}
|
||||
|
||||
template<typename T, typename enable_if<!is_same<T, double>{}>::type* = nullptr>
|
||||
__device__
|
||||
void testKernelExch(T* g_odata) {
|
||||
// access thread id
|
||||
const T tid = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
// Atomic exchange
|
||||
atomicExch(&g_odata[2], tid);
|
||||
}
|
||||
|
||||
__device__
|
||||
void testKernelSub(...) {}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename enable_if<
|
||||
is_same<T, int>{} || is_same<T, unsigned int>{}>::type* = nullptr>
|
||||
__device__
|
||||
void testKernelSub(T* g_odata) {
|
||||
// Atomic subtraction (final should be 0)
|
||||
atomicSub(&g_odata[1], 10);
|
||||
}
|
||||
|
||||
__device__
|
||||
void testKernelIntegral(...) {}
|
||||
|
||||
template<typename T, typename enable_if<is_integral<T>{}>::type* = nullptr>
|
||||
__device__
|
||||
void testKernelIntegral(T* g_odata) {
|
||||
// access thread id
|
||||
const T tid = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
// Atomic maximum
|
||||
atomicMax(&g_odata[3], tid);
|
||||
// Atomic minimum
|
||||
atomicMin(&g_odata[4], tid);
|
||||
// Atomic increment (modulo 17+1)
|
||||
atomicInc((unsigned int*)&g_odata[5], 17);
|
||||
// Atomic decrement
|
||||
atomicDec((unsigned int*)&g_odata[6], 137);
|
||||
// Atomic compare-and-swap
|
||||
atomicCAS(&g_odata[7], tid - 1, tid);
|
||||
// Atomic AND
|
||||
atomicAnd(&g_odata[8], 2 * tid + 7);
|
||||
// Atomic OR
|
||||
atomicOr(&g_odata[9], 1 << tid);
|
||||
// Atomic XOR
|
||||
atomicXor(&g_odata[10], tid);
|
||||
testKernelSub(g_odata);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
__global__ void testKernel(T* g_odata) {
|
||||
// Atomic addition
|
||||
atomicAdd(&g_odata[0], 10);
|
||||
testKernelIntegral(g_odata);
|
||||
testKernelExch(g_odata);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void runTest() {
|
||||
// CHECK: hipDeviceProp_t deviceProp;
|
||||
cudaDeviceProp deviceProp;
|
||||
deviceProp.major = 0;
|
||||
deviceProp.minor = 0;
|
||||
int dev = 0;
|
||||
// CHECK: hipGetDeviceProperties(&deviceProp, dev);
|
||||
cudaGetDeviceProperties(&deviceProp, dev);
|
||||
// Statistics about the GPU device
|
||||
printf(
|
||||
"> GPU device has %d Multi-Processors, "
|
||||
"SM %d.%d compute capabilities\n\n",
|
||||
deviceProp.multiProcessorCount, deviceProp.major, deviceProp.minor);
|
||||
unsigned int numThreads = 256;
|
||||
unsigned int numBlocks = 64;
|
||||
unsigned int numData = 11;
|
||||
unsigned int memSize = sizeof(T) * numData;
|
||||
|
||||
// Allocate mem for the result on host side
|
||||
T* hOData = (T*)malloc(memSize);
|
||||
// Initialize the memory
|
||||
for (unsigned int i = 0; i < numData; i++) hOData[i] = 0;
|
||||
// To make the AND and XOR tests generate something other than 0...
|
||||
hOData[8] = hOData[10] = 0xff;
|
||||
// Allocate device memory for result
|
||||
T* dOData;
|
||||
// CHECK: hipMalloc((void**)&dOData, memSize);
|
||||
cudaMalloc((void**)&dOData, memSize);
|
||||
// Copy host memory to device to initialize to zero
|
||||
// CHECK: hipMemcpy(dOData, hOData, memSize, hipMemcpyHostToDevice);
|
||||
cudaMemcpy(dOData, hOData, memSize, cudaMemcpyHostToDevice);
|
||||
// Execute the kernel
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(testKernel), dim3(numBlocks), dim3(numThreads), 0, 0, dOData);
|
||||
testKernel<<<numBlocks, numThreads>>>(dOData);
|
||||
// Copy result from device to host
|
||||
// CHECK: hipMemcpy(hOData, dOData, memSize, hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(hOData, dOData, memSize, cudaMemcpyDeviceToHost);
|
||||
// Compute reference solution
|
||||
testResult = computeGold(hOData, numThreads * numBlocks);
|
||||
// Cleanup memory
|
||||
free(hOData);
|
||||
// CHECK: hipFree(dOData);
|
||||
cudaFree(dOData);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
printf("%s starting...\n", sampleName);
|
||||
runTest<int>();
|
||||
runTest<unsigned int>();
|
||||
runTest<unsigned long long>();
|
||||
runTest<float>();
|
||||
#if CUDA_VERSION >= 8000 && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 600
|
||||
runTest<double>();
|
||||
#endif
|
||||
// CHECK: hipDeviceReset();
|
||||
cudaDeviceReset();
|
||||
printf("%s completed, returned %s\n", sampleName, testResult ? "OK" : "ERROR!");
|
||||
exit(testResult ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
/*
|
||||
Copyright (c) 2015-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.
|
||||
*/
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
|
||||
#define NUM 1024
|
||||
#define SIZE 1024 * 4
|
||||
|
||||
__device__ int globalIn[NUM];
|
||||
__device__ int globalOut[NUM];
|
||||
|
||||
__global__ void Assign(int* Out) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
Out[tid] = globalIn[tid];
|
||||
globalOut[tid] = globalIn[tid];
|
||||
}
|
||||
|
||||
__device__ __constant__ int globalConst[NUM];
|
||||
|
||||
__global__ void checkAddress(int* addr, bool* out) {
|
||||
*out = (globalConst == addr);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int *A, *Am, *B, *Ad, *C, *Cm;
|
||||
A = new int[NUM];
|
||||
B = new int[NUM];
|
||||
C = new int[NUM];
|
||||
for (int i = 0; i < NUM; ++i) {
|
||||
A[i] = -1 * i;
|
||||
B[i] = 0;
|
||||
C[i] = 0;
|
||||
}
|
||||
// CHECK: hipMalloc((void**)&Ad, SIZE);
|
||||
cudaMalloc((void**)&Ad, SIZE);
|
||||
// CHECK: hipHostMalloc((void**)&Am, SIZE);
|
||||
cudaMallocHost((void**)&Am, SIZE);
|
||||
// CHECK: hipHostMalloc((void**)&Cm, SIZE);
|
||||
cudaMallocHost((void**)&Cm, SIZE);
|
||||
for (int i = 0; i < NUM; ++i) {
|
||||
Am[i] = -1 * i;
|
||||
Cm[i] = 0;
|
||||
}
|
||||
// CHECK: hipStream_t stream = NULL;
|
||||
cudaStream_t stream = NULL;
|
||||
// CHECK: hipStreamCreate(&stream);
|
||||
cudaStreamCreate(&stream);
|
||||
// CHECK: hipMemcpyToSymbolAsync(HIP_SYMBOL(globalIn), Am, SIZE, 0, hipMemcpyHostToDevice, stream);
|
||||
cudaMemcpyToSymbolAsync(globalIn, Am, SIZE, 0, cudaMemcpyHostToDevice, stream);
|
||||
// CHECK: hipStreamSynchronize(stream);
|
||||
cudaStreamSynchronize(stream);
|
||||
// CHECK: hipLaunchKernelGGL(Assign, dim3(1, 1, 1), dim3(NUM, 1, 1), 0, 0, Ad);
|
||||
Assign<<<dim3(1, 1, 1), dim3(NUM, 1, 1)>>>(Ad);
|
||||
// CHECK: hipMemcpy(B, Ad, SIZE, hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(B, Ad, SIZE, cudaMemcpyDeviceToHost);
|
||||
// CHECK: hipMemcpyFromSymbolAsync(Cm, HIP_SYMBOL(globalOut), SIZE, 0, hipMemcpyDeviceToHost, stream);
|
||||
cudaMemcpyFromSymbolAsync(Cm, globalOut, SIZE, 0, cudaMemcpyDeviceToHost, stream);
|
||||
// CHECK: hipStreamSynchronize(stream);
|
||||
cudaStreamSynchronize(stream);
|
||||
for (int i = 0; i < NUM; ++i) {
|
||||
assert(Am[i] == B[i]);
|
||||
assert(Am[i] == Cm[i]);
|
||||
}
|
||||
for (int i = 0; i < NUM; ++i) {
|
||||
A[i] = -2 * i;
|
||||
B[i] = 0;
|
||||
}
|
||||
// CHECK: hipMemcpyToSymbol(HIP_SYMBOL(globalIn), A, SIZE, 0, hipMemcpyHostToDevice);
|
||||
cudaMemcpyToSymbol(globalIn, A, SIZE, 0, cudaMemcpyHostToDevice);
|
||||
// CHECK: hipLaunchKernelGGL(Assign, dim3(1, 1, 1), dim3(NUM, 1, 1), 0, 0, Ad);
|
||||
Assign<<<dim3(1, 1, 1), dim3(NUM, 1, 1)>>>(Ad);
|
||||
// CHECK: hipMemcpy(B, Ad, SIZE, hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(B, Ad, SIZE, cudaMemcpyDeviceToHost);
|
||||
// CHECK: hipMemcpyFromSymbol(C, HIP_SYMBOL(globalOut), SIZE, 0, hipMemcpyDeviceToHost);
|
||||
cudaMemcpyFromSymbol(C, globalOut, SIZE, 0, cudaMemcpyDeviceToHost);
|
||||
for (int i = 0; i < NUM; ++i) {
|
||||
assert(A[i] == B[i]);
|
||||
assert(A[i] == C[i]);
|
||||
}
|
||||
for (int i = 0; i < NUM; ++i) {
|
||||
A[i] = -3 * i;
|
||||
B[i] = 0;
|
||||
}
|
||||
// CHECK: hipMemcpyToSymbolAsync(HIP_SYMBOL(globalIn), A, SIZE, 0, hipMemcpyHostToDevice, stream);
|
||||
cudaMemcpyToSymbolAsync(globalIn, A, SIZE, 0, cudaMemcpyHostToDevice, stream);
|
||||
// CHECK: hipStreamSynchronize(stream);
|
||||
cudaStreamSynchronize(stream);
|
||||
// CHECK: hipLaunchKernelGGL(Assign, dim3(1, 1, 1), dim3(NUM, 1, 1), 0, 0, Ad);
|
||||
Assign<<<dim3(1, 1, 1), dim3(NUM, 1, 1)>>>(Ad);
|
||||
// CHECK: hipMemcpy(B, Ad, SIZE, hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(B, Ad, SIZE, cudaMemcpyDeviceToHost);
|
||||
// CHECK: hipMemcpyFromSymbolAsync(C, HIP_SYMBOL(globalOut), SIZE, 0, hipMemcpyDeviceToHost, stream);
|
||||
cudaMemcpyFromSymbolAsync(C, globalOut, SIZE, 0, cudaMemcpyDeviceToHost, stream);
|
||||
// CHECK: hipStreamSynchronize(stream);
|
||||
cudaStreamSynchronize(stream);
|
||||
for (int i = 0; i < NUM; ++i) {
|
||||
assert(A[i] == B[i]);
|
||||
assert(A[i] == C[i]);
|
||||
}
|
||||
bool *checkOkD;
|
||||
bool checkOk = false;
|
||||
size_t symbolSize = 0;
|
||||
int *symbolAddress;
|
||||
// CHECK: hipGetSymbolSize(&symbolSize, HIP_SYMBOL(globalConst));
|
||||
cudaGetSymbolSize(&symbolSize, globalConst);
|
||||
// CHECK: hipGetSymbolAddress((void**) &symbolAddress, HIP_SYMBOL(globalConst));
|
||||
cudaGetSymbolAddress((void**) &symbolAddress, globalConst);
|
||||
// CHECK: hipMalloc((void**)&checkOkD, sizeof(bool));
|
||||
cudaMalloc((void**)&checkOkD, sizeof(bool));
|
||||
// CHECK: hipLaunchKernelGGL(checkAddress, dim3(1, 1, 1), dim3(1, 1, 1), 0, 0, symbolAddress, checkOkD);
|
||||
checkAddress<<<dim3(1, 1, 1), dim3(1, 1, 1)>>>(symbolAddress, checkOkD);
|
||||
// CHECK: hipMemcpy(&checkOk, checkOkD, sizeof(bool), hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(&checkOk, checkOkD, sizeof(bool), cudaMemcpyDeviceToHost);
|
||||
// CHECK: hipFree(checkOkD);
|
||||
cudaFree(checkOkD);
|
||||
assert(checkOk);
|
||||
assert(symbolSize == SIZE);
|
||||
// CHECK: hipHostFree(Am);
|
||||
cudaFreeHost(Am);
|
||||
// CHECK: hipHostFree(Cm);
|
||||
cudaFreeHost(Cm);
|
||||
// CHECK: hipFree(Ad);
|
||||
cudaFree(Ad);
|
||||
delete[] A;
|
||||
delete[] B;
|
||||
delete[] C;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
// Synthetic test to warn only on device functions umin and umax as unsupported, but not on user defined ones.
|
||||
// ToDo: change lit testing in order to parse the output.
|
||||
|
||||
#define LEN 1024
|
||||
#define SIZE LEN * sizeof(float)
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace my {
|
||||
// user defined function
|
||||
unsigned int umin(unsigned int arg1, unsigned int arg2) {
|
||||
return (arg1 < arg2) ? arg1 : arg2;
|
||||
}
|
||||
// user defined function
|
||||
unsigned int umax(unsigned int arg1, unsigned int arg2) {
|
||||
return (arg1 > arg2) ? arg1 : arg2;
|
||||
}
|
||||
}
|
||||
|
||||
__global__ void uint_arithm(float* A, float* B, float* C, unsigned int u1, unsigned int u2)
|
||||
{
|
||||
// device function call (warn if unsupported)
|
||||
unsigned int _umin = umin ( u1, u2 );
|
||||
// device function call (warn if unsupported)
|
||||
unsigned int _umax = umax ( u1, u2 );
|
||||
// device function call (warn if unsupported)
|
||||
unsigned int _umin_global = ::umin ( u1, u2 );
|
||||
// device function call (warn if unsupported)
|
||||
unsigned int _umax_global = ::umax(u1, u2);
|
||||
if (_umin != _umin_global) return;
|
||||
if (_umax != _umax_global) return;
|
||||
int i = threadIdx.x;
|
||||
A[i] = i + _umin;
|
||||
B[i] = i + _umax;
|
||||
C[i] = A[i] + B[i];
|
||||
}
|
||||
|
||||
int main() {
|
||||
unsigned int u1 = 33;
|
||||
unsigned int u2 = 34;
|
||||
// user defined function call
|
||||
unsigned int _min = my::umin(u1, u2);
|
||||
// user defined function call
|
||||
unsigned int _max = my::umax(u1, u2);
|
||||
float *A, *B, *C;
|
||||
// CHECK: hipMalloc((void**)&A, SIZE);
|
||||
cudaMalloc((void**)&A, SIZE);
|
||||
// CHECK: hipMalloc((void**)&B, SIZE);
|
||||
cudaMalloc((void**)&B, SIZE);
|
||||
// CHECK: hipMalloc((void**)&C, SIZE);
|
||||
cudaMalloc((void**)&C, SIZE);
|
||||
dim3 dimGrid(LEN / 512, 1, 1);
|
||||
dim3 dimBlock(512, 1, 1);
|
||||
// CHECK: hipLaunchKernelGGL(uint_arithm, dim3(dimGrid), dim3(dimBlock), 0, 0, A, B, C, u1, u2);
|
||||
uint_arithm<<<dimGrid, dimBlock>>>(A, B, C, u1, u2);
|
||||
return _min < _max;
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
// CHECK-NOT: #include <cuda_runtime.h>
|
||||
// CHECK: #include <stdio.h>
|
||||
#include <cuda.h>
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdio.h>
|
||||
@@ -1,8 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// CHECK: #include "hip/hip_runtime.h"
|
||||
// CHECK-NOT: #include "cuda_runtime.h"
|
||||
// CHECK: #include <stdio.h>
|
||||
#include "cuda.h"
|
||||
#include "cuda_runtime.h"
|
||||
#include <stdio.h>
|
||||
@@ -1,10 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// CHECK: #pragma once
|
||||
// CHECK-NEXT: #include <hip/hip_runtime.h>
|
||||
#pragma once
|
||||
// CHECK-NOT: #include <hip/hip_runtime.h>
|
||||
int main(int argc, char* argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
// CHECK-NEXT: #include <stdio.h>
|
||||
// CHECK-NEXT: #include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
// CHECK-NOT: #include <hip/hip_runtime.h>
|
||||
int main(int argc, char* argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// CHECK: #pragma once
|
||||
// CHECK-NEXT: #include <hip/hip_runtime.h>
|
||||
#pragma once
|
||||
// CHECK-NOT: #include <hip/hip_runtime.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// CHECK: #include <hipblas.h>
|
||||
// CHECK-NOT: #include <cublas_v2.h>
|
||||
// CHECK: #include <stdio.h>
|
||||
#include <cublas.h>
|
||||
#include <cublas_v2.h>
|
||||
#include <stdio.h>
|
||||
@@ -1,8 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// CHECK: #include "hipblas.h"
|
||||
// CHECK-NOT: #include "cublas.h"
|
||||
// CHECK: #include <stdio.h>
|
||||
#include "cublas_v2.h"
|
||||
#include "cublas.h"
|
||||
#include <stdio.h>
|
||||
@@ -1,14 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
// CHECK-NOT: #include <cuda_runtime.h>
|
||||
// CHECK: #include <iostream>
|
||||
// CHECK: #include "hipblas.h"
|
||||
// CHECK-NOT: #include "cublas.h"
|
||||
// CHECK: #include <stdio.h>
|
||||
#include <cuda.h>
|
||||
#include <cuda_runtime.h>
|
||||
#include <iostream>
|
||||
#include "cublas_v2.h"
|
||||
#include "cublas.h"
|
||||
#include <stdio.h>
|
||||
@@ -1,100 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
// CHECK: #include <memory>
|
||||
|
||||
// CHECK-NOT: #include <cuda_runtime.h>
|
||||
// CHECK-NOT: #include <hip/hip_runtime.h>
|
||||
|
||||
// CHECK: #include "hip/hip_runtime_api.h"
|
||||
// CHECK: #include "hip/channel_descriptor.h"
|
||||
// CHECK: #include "hip/device_functions.h"
|
||||
// CHECK: #include "hip/driver_types.h"
|
||||
// CHECK: #include "hip/hip_complex.h"
|
||||
// CHECK: #include "hip/hip_fp16.h"
|
||||
// CHECK: #include "hip/hip_texture_types.h"
|
||||
// CHECK: #include "hip/hip_vector_types.h"
|
||||
|
||||
// CHECK: #include <iostream>
|
||||
|
||||
// CHECK: #include "hipblas.h"
|
||||
// CHECK-NOT: #include "cublas.h"
|
||||
|
||||
// CHECK: #include <stdio.h>
|
||||
|
||||
// CHECK: #include "hiprand.h"
|
||||
// CHECK: #include "hiprand_kernel.h"
|
||||
|
||||
// CHECK: #include <algorithm>
|
||||
|
||||
// CHECK-NOT: #include "hiprand.h"
|
||||
// CHECK-NOT: #include "hiprand_kernel.h"
|
||||
// CHECK-NOT: #include "curand_discrete.h"
|
||||
// CHECK-NOT: #include "curand_discrete2.h"
|
||||
// CHECK-NOT: #include "curand_globals.h"
|
||||
// CHECK-NOT: #include "curand_lognormal.h"
|
||||
// CHECK-NOT: #include "curand_mrg32k3a.h"
|
||||
// CHECK-NOT: #include "curand_mtgp32.h"
|
||||
// CHECK-NOT: #include "curand_mtgp32_host.h"
|
||||
// CHECK-NOT: #include "curand_mtgp32_kernel.h"
|
||||
// CHECK-NOT: #include "curand_mtgp32dc_p_11213.h"
|
||||
// CHECK-NOT: #include "curand_normal.h"
|
||||
// CHECK-NOT: #include "curand_normal_static.h"
|
||||
// CHECK-NOT: #include "curand_philox4x32_x.h"
|
||||
// CHECK-NOT: #include "curand_poisson.h"
|
||||
// CHECK-NOT: #include "curand_precalc.h"
|
||||
// CHECK-NOT: #include "curand_uniform.h"
|
||||
|
||||
// CHECK: #include <string>
|
||||
|
||||
// CHECK: #include "hipfft.h"
|
||||
// CHECK: #include "hipsparse.h"
|
||||
|
||||
#include <cuda.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <cuda_runtime.h>
|
||||
|
||||
#include "cuda_runtime_api.h"
|
||||
#include "channel_descriptor.h"
|
||||
#include "device_functions.h"
|
||||
#include "driver_types.h"
|
||||
#include "cuComplex.h"
|
||||
#include "cuda_fp16.h"
|
||||
#include "cuda_texture_types.h"
|
||||
#include "vector_types.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "cublas_v2.h"
|
||||
#include "cublas.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "curand.h"
|
||||
#include "curand_kernel.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "curand_discrete.h"
|
||||
#include "curand_discrete2.h"
|
||||
#include "curand_globals.h"
|
||||
#include "curand_lognormal.h"
|
||||
#include "curand_mrg32k3a.h"
|
||||
#include "curand_mtgp32.h"
|
||||
#include "curand_mtgp32_host.h"
|
||||
#include "curand_mtgp32_kernel.h"
|
||||
#include "curand_mtgp32dc_p_11213.h"
|
||||
#include "curand_normal.h"
|
||||
#include "curand_normal_static.h"
|
||||
#include "curand_philox4x32_x.h"
|
||||
#include "curand_poisson.h"
|
||||
#include "curand_precalc.h"
|
||||
#include "curand_uniform.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "cufft.h"
|
||||
|
||||
#include "cusparse.h"
|
||||
@@ -1,14 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// Checks that HIP header file is included after #pragma once,
|
||||
// which goes before include guard controlling macro.
|
||||
// CHECK: #pragma once
|
||||
// CHECK-NEXT: #include <hip/hip_runtime.h>
|
||||
#pragma once
|
||||
#ifndef HEADERS_TEST_10_H
|
||||
// CHECK: #ifndef HEADERS_TEST_10_H
|
||||
// CHECK-NOT: #include <hip/hip_runtime.h>
|
||||
#define HEADERS_TEST_10_H
|
||||
#include <stdio.h>
|
||||
static int counter = 0;
|
||||
#endif // HEADERS_TEST_10_H
|
||||
@@ -1,14 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// Checks that HIP header file is included after include guard controlling macro,
|
||||
// which goes before #pragma once.
|
||||
// CHECK: #ifndef HEADERS_TEST_10_H
|
||||
// CHECK-NEXT: #include <hip/hip_runtime.h>
|
||||
#ifndef HEADERS_TEST_10_H
|
||||
// CHECK: #pragma once
|
||||
#pragma once
|
||||
// CHECK-NOT: #include <hip/hip_runtime.h>
|
||||
#define HEADERS_TEST_10_H
|
||||
#include <stdio.h>
|
||||
static int counter = 0;
|
||||
#endif // HEADERS_TEST_10_H
|
||||
@@ -1,46 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
// Synthetic test to warn only on device functions umin and umax as unsupported, but not on user defined ones.
|
||||
// ToDo: change lit testing in order to parse the output.
|
||||
|
||||
#define LEN 1024
|
||||
#define SIZE LEN * sizeof(float)
|
||||
#define ITER 1024*1024
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <algorithm>
|
||||
|
||||
#define CUDA_LAUNCH(cuda_call,dimGrid,dimBlock, ...) \
|
||||
cuda_call<<<dimGrid,dimBlock>>>(__VA_ARGS__);
|
||||
|
||||
__global__ void Inc1(float *Ad, float *Bd) {
|
||||
int tx = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
if (tx < 1) {
|
||||
for (int i = 0; i < ITER; ++i) {
|
||||
Ad[tx] = Ad[tx] + 1.0f;
|
||||
for (int j = 0; j < 256; ++j) {
|
||||
Bd[tx] = Ad[tx];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
float *A, *Ad, *Bd;
|
||||
A = new float[LEN];
|
||||
for (int i = 0; i < LEN; ++i) {
|
||||
A[i] = 0.0f;
|
||||
}
|
||||
// CHECK: hipError_t status;
|
||||
cudaError_t status;
|
||||
// CHECK: status = hipHostRegister(A, SIZE, hipHostRegisterMapped);
|
||||
status = cudaHostRegister(A, SIZE, cudaHostRegisterMapped);
|
||||
// CHECK: hipHostGetDevicePointer(&Ad, A, 0);
|
||||
cudaHostGetDevicePointer(&Ad, A, 0);
|
||||
// CHECK: hipMalloc((void**)&Bd, SIZE);
|
||||
cudaMalloc((void**)&Bd, SIZE);
|
||||
dim3 dimGrid(LEN / 512, 1, 1);
|
||||
dim3 dimBlock(512, 1, 1);
|
||||
|
||||
// CHECK: hipLaunchKernelGGL(Inc1, dim3(dimGrid), dim3(dimBlock), 0, 0, Ad, Bd);
|
||||
CUDA_LAUNCH(Inc1, dimGrid, dimBlock, Ad, Bd);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef CAFFE2_CORE_COMMON_CUDNN_H_
|
||||
#define CAFFE2_CORE_COMMON_CUDNN_H_
|
||||
|
||||
#include <array>
|
||||
#include <mutex>
|
||||
|
||||
#endif // CAFFE2_CORE_COMMON_CUDNN_H_
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
#ifndef CAFFE2_OPERATORS_SPATIAL_BATCH_NORM_OP_H_
|
||||
#define CAFFE2_OPERATORS_SPATIAL_BATCH_NORM_OP_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace caffe2 {
|
||||
|
||||
} // namespace caffe2
|
||||
|
||||
#endif // CAFFE2_OPERATORS_SPATIAL_BATCH_NORM_OP_H_
|
||||
@@ -1,12 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args "-roc" %clang_args
|
||||
|
||||
// NOTE: Nonworking code just for conversion testing
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
// CHECK: #include "caffe2/operators/hip/spatial_batch_norm_op_miopen.hip"
|
||||
#include "caffe2/operators/spatial_batch_norm_op.h"
|
||||
// CHECK: #include "caffe2/core/hip/common_miopen.h"
|
||||
#include "caffe2/core/common_cudnn.h"
|
||||
@@ -1,102 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args "-roc" %clang_args
|
||||
|
||||
// NOTE: Nonworking code just for conversion testing
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string>
|
||||
|
||||
namespace caffe2 {
|
||||
|
||||
// Operator Definition.
|
||||
struct OperatorDef {
|
||||
int input = 1;
|
||||
int output = 2;
|
||||
int name = 3;
|
||||
};
|
||||
|
||||
class OperatorBase;
|
||||
class Workspace;
|
||||
|
||||
template <class T>
|
||||
class Observable {
|
||||
public:
|
||||
Observable() = default;
|
||||
|
||||
Observable(Observable&&) = default;
|
||||
Observable& operator =(Observable&&) = default;
|
||||
|
||||
virtual ~Observable() = default;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class ObserverBase {
|
||||
public:
|
||||
explicit ObserverBase(T* subject) : subject_(subject) {}
|
||||
|
||||
virtual void Start() {}
|
||||
virtual void Stop() {}
|
||||
|
||||
virtual std::string debugInfo() {
|
||||
return "Not implemented.";
|
||||
}
|
||||
|
||||
virtual ~ObserverBase() noexcept {};
|
||||
|
||||
T* subject() const {
|
||||
return subject_;
|
||||
}
|
||||
|
||||
protected:
|
||||
T* subject_;
|
||||
};
|
||||
|
||||
typedef ObserverBase<OperatorBase> OperatorObserver;
|
||||
|
||||
class OperatorBase : public Observable<OperatorBase> {
|
||||
public:
|
||||
explicit OperatorBase(const OperatorDef& operator_def, Workspace* ws);
|
||||
virtual ~OperatorBase() noexcept {}
|
||||
};
|
||||
|
||||
template <class Context>
|
||||
class Operator : public OperatorBase {
|
||||
public:
|
||||
explicit Operator(const OperatorDef& operator_def, Workspace* ws)
|
||||
: OperatorBase(operator_def, ws) {
|
||||
}
|
||||
~Operator() noexcept override {}
|
||||
};
|
||||
|
||||
template <class Context>
|
||||
class DummyEmptyOp : public Operator<Context> {
|
||||
public:
|
||||
DummyEmptyOp(const OperatorDef& def, Workspace* ws)
|
||||
: Operator<Context>(def, ws) {}
|
||||
|
||||
bool RunOnDevice() final { return true; }
|
||||
};
|
||||
|
||||
|
||||
class CUDAContext {
|
||||
public:
|
||||
CUDAContext();
|
||||
virtual ~CUDAContext() noexcept {}
|
||||
};
|
||||
|
||||
#define REGISTER_CUDA_OPERATOR(name, ...) \
|
||||
void CAFFE2_PLEASE_ADD_OPERATOR_SCHEMA_FOR_##name(); \
|
||||
static void CAFFE_ANONYMOUS_VARIABLE_CUDA##name() { \
|
||||
CAFFE2_PLEASE_ADD_OPERATOR_SCHEMA_FOR_##name(); \
|
||||
}
|
||||
|
||||
#define REGISTER_CUDA_OPERATOR_CREATOR(key, ...)
|
||||
|
||||
// CHECK: REGISTER_HIP_OPERATOR(Operator, DummyEmptyOp<HIPContext>);
|
||||
REGISTER_CUDA_OPERATOR(Operator, DummyEmptyOp<CUDAContext>);
|
||||
// CHECK: REGISTER_HIP_OPERATOR_CREATOR(Operator, DummyEmptyOp<HIPContext>);
|
||||
REGISTER_CUDA_OPERATOR_CREATOR(Operator, DummyEmptyOp<CUDAContext>);
|
||||
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
// CHECK: #include <hiprand.h>
|
||||
#include <curand.h>
|
||||
// CHECK: #include <hipcub/hipcub.hpp>
|
||||
#include <cub/cub.cuh>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// TODO:
|
||||
// using namespace cub;
|
||||
|
||||
template <typename T>
|
||||
__global__ void sort(const T* data_in, T* data_out){
|
||||
// CHECK: typedef ::hipcub::BlockRadixSort<T, 1024, 4> BlockRadixSortT;
|
||||
typedef ::cub::BlockRadixSort<T, 1024, 4> BlockRadixSortT;
|
||||
__shared__ typename BlockRadixSortT::TempStorage tmp_sort;
|
||||
double items[4];
|
||||
int i0 = 4 * (blockIdx.x * blockDim.x + threadIdx.x);
|
||||
for (int i = 0; i < 4; ++i){
|
||||
items[i] = data_in[i0 + i];
|
||||
}
|
||||
BlockRadixSortT(tmp_sort).Sort(items);
|
||||
for (int i = 0; i < 4; ++i){
|
||||
data_out[i0 + i] = items[i];
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
double* d_gpu = NULL;
|
||||
double* result_gpu = NULL;
|
||||
double* data_sorted = new double[4096];
|
||||
// Allocate memory on the GPU
|
||||
// CHECK: hipMalloc(&d_gpu, 4096 * sizeof(double));
|
||||
cudaMalloc(&d_gpu, 4096 * sizeof(double));
|
||||
// CHECK: hipMalloc(&result_gpu, 4096 * sizeof(double));
|
||||
cudaMalloc(&result_gpu, 4096 * sizeof(double));
|
||||
// CHECK: hiprandGenerator_t gen;
|
||||
curandGenerator_t gen;
|
||||
// Create generator
|
||||
// CHECK: hiprandCreateGenerator(&gen, HIPRAND_RNG_PSEUDO_DEFAULT);
|
||||
curandCreateGenerator(&gen, CURAND_RNG_PSEUDO_DEFAULT);
|
||||
// Fill array with random numbers
|
||||
// CHECK: hiprandGenerateNormalDouble(gen, d_gpu, 4096, 0.0, 1.0);
|
||||
curandGenerateNormalDouble(gen, d_gpu, 4096, 0.0, 1.0);
|
||||
// Destroy generator
|
||||
// CHECK: hiprandDestroyGenerator(gen);
|
||||
curandDestroyGenerator(gen);
|
||||
// Sort data
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(sort), dim3(1), dim3(1024), 0, 0, d_gpu, result_gpu);
|
||||
sort<<<1, 1024>>>(d_gpu, result_gpu);
|
||||
// CHECK: hipMemcpy(data_sorted, result_gpu, 4096 * sizeof(double), hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(data_sorted, result_gpu, 4096 * sizeof(double), cudaMemcpyDeviceToHost);
|
||||
// Write the sorted data to standard out
|
||||
for (int i = 0; i < 4096; ++i){
|
||||
std::cout << data_sorted[i] << ", ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
// CHECK: #include <hiprand.h>
|
||||
#include <curand.h>
|
||||
// CHECK: #include <hipcub/hipcub.hpp>
|
||||
#include <cub/cub.cuh>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
template <int BLOCK_WIDTH, int ITEMS_PER_THREAD,
|
||||
// CHECK: hipcub::BlockLoadAlgorithm BLOCK_LOAD_ALGO,
|
||||
cub::BlockLoadAlgorithm BLOCK_LOAD_ALGO,
|
||||
// CHECK: hipcub::BlockStoreAlgorithm BLOCK_STORE_ALGO,
|
||||
cub::BlockStoreAlgorithm BLOCK_STORE_ALGO,
|
||||
typename T>
|
||||
__global__ void sort(const T* data_in, T* data_out){
|
||||
// CHECK: typedef hipcub::BlockLoad<T, BLOCK_WIDTH, ITEMS_PER_THREAD, BLOCK_LOAD_ALGO> BlockLoadT;
|
||||
typedef cub::BlockLoad<T, BLOCK_WIDTH, ITEMS_PER_THREAD, BLOCK_LOAD_ALGO> BlockLoadT;
|
||||
// CHECK: typedef hipcub::BlockRadixSort<T, BLOCK_WIDTH, ITEMS_PER_THREAD> BlockRadixSortT;
|
||||
typedef cub::BlockRadixSort<T, BLOCK_WIDTH, ITEMS_PER_THREAD> BlockRadixSortT;
|
||||
// CHECK: typedef hipcub::BlockStore<T, BLOCK_WIDTH, ITEMS_PER_THREAD, BLOCK_STORE_ALGO> BlockStoreT;
|
||||
typedef cub::BlockStore<T, BLOCK_WIDTH, ITEMS_PER_THREAD, BLOCK_STORE_ALGO> BlockStoreT;
|
||||
__shared__ union {
|
||||
typename BlockLoadT::TempStorage load;
|
||||
typename BlockRadixSortT::TempStorage sort;
|
||||
typename BlockStoreT::TempStorage store;
|
||||
} tmp_storage;
|
||||
T items[ITEMS_PER_THREAD];
|
||||
BlockLoadT(tmp_storage.load).Load(data_in + blockIdx.x * BLOCK_WIDTH * ITEMS_PER_THREAD, items);
|
||||
__syncthreads();
|
||||
BlockRadixSortT(tmp_storage.sort).Sort(items);
|
||||
__syncthreads();
|
||||
BlockStoreT(tmp_storage.store).Store(data_out + blockIdx.x * BLOCK_WIDTH * ITEMS_PER_THREAD, items);
|
||||
}
|
||||
|
||||
int main() {
|
||||
double* d_gpu = NULL;
|
||||
double* result_gpu = NULL;
|
||||
double* data_sorted = new double[1000*4096];
|
||||
// Allocate memory on the GPU
|
||||
// CHECK: hipMalloc(&d_gpu, 1000*4096 * sizeof(double));
|
||||
cudaMalloc(&d_gpu, 1000*4096 * sizeof(double));
|
||||
// CHECK: hipMalloc(&result_gpu, 1000*4096 * sizeof(double));
|
||||
cudaMalloc(&result_gpu, 1000*4096 * sizeof(double));
|
||||
// CHECK: hiprandGenerator_t gen;
|
||||
curandGenerator_t gen;
|
||||
// Create generator
|
||||
// CHECK: hiprandCreateGenerator(&gen, HIPRAND_RNG_PSEUDO_DEFAULT);
|
||||
curandCreateGenerator(&gen, CURAND_RNG_PSEUDO_DEFAULT);
|
||||
// Fill array with random numbers
|
||||
// CHECK: hiprandGenerateNormalDouble(gen, d_gpu, 1000*4096, 0.0, 1.0);
|
||||
curandGenerateNormalDouble(gen, d_gpu, 1000*4096, 0.0, 1.0);
|
||||
// Destroy generator
|
||||
// CHECK: hiprandDestroyGenerator(gen);
|
||||
curandDestroyGenerator(gen);
|
||||
// Sort data
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(sort<512, 8, hipcub::BLOCK_LOAD_TRANSPOSE, hipcub::BLOCK_STORE_TRANSPOSE>), dim3(1000), dim3(512), 0, 0, d_gpu, result_gpu);
|
||||
sort<512, 8, cub::BLOCK_LOAD_TRANSPOSE, cub::BLOCK_STORE_TRANSPOSE><<<1000, 512>>>(d_gpu, result_gpu);
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(sort<256, 16, hipcub::BLOCK_LOAD_DIRECT, hipcub::BLOCK_STORE_DIRECT>), dim3(1000), dim3(256), 0, 0, d_gpu, result_gpu);
|
||||
sort<256, 16, cub::BLOCK_LOAD_DIRECT, cub::BLOCK_STORE_DIRECT><<<1000, 256>>>(d_gpu, result_gpu);
|
||||
// CHECK: hipMemcpy(data_sorted, result_gpu, 1000*4096*sizeof(double), hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(data_sorted, result_gpu, 1000*4096*sizeof(double), cudaMemcpyDeviceToHost);
|
||||
// Write the sorted data to standard out
|
||||
for (int i = 0; i < 4095; ++i) {
|
||||
std::cout << data_sorted[i] << ", ";
|
||||
}
|
||||
std::cout << data_sorted[4095] << std::endl;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <iostream>
|
||||
// CHECK: #include <hipcub/hipcub.hpp>
|
||||
#include <cub/cub.cuh>
|
||||
|
||||
// using namespace hipcub;
|
||||
using namespace cub;
|
||||
|
||||
// Simple CUDA kernel for computing tiled partial sums
|
||||
template <int BLOCK_THREADS, int ITEMS_PER_THREAD,
|
||||
// CHECK: hipcub::BlockLoadAlgorithm LOAD_ALGO,
|
||||
cub::BlockLoadAlgorithm LOAD_ALGO,
|
||||
// CHECK: hipcub::BlockScanAlgorithm SCAN_ALGO>
|
||||
cub::BlockScanAlgorithm SCAN_ALGO>
|
||||
__global__ void ScanTilesKernel(int *d_in, int *d_out) {
|
||||
// Specialize collective types for problem context
|
||||
// CHECK: typedef ::hipcub::BlockLoad<int*, BLOCK_THREADS, ITEMS_PER_THREAD, LOAD_ALGO> BlockLoadT;
|
||||
typedef ::cub::BlockLoad<int*, BLOCK_THREADS, ITEMS_PER_THREAD, LOAD_ALGO> BlockLoadT;
|
||||
typedef BlockScan<int, BLOCK_THREADS, SCAN_ALGO> BlockScanT;
|
||||
// Allocate on-chip temporary storage
|
||||
__shared__ union {
|
||||
typename BlockLoadT::TempStorage load;
|
||||
typename BlockScanT::TempStorage reduce;
|
||||
} temp_storage;
|
||||
// Load data per thread
|
||||
int thread_data[ITEMS_PER_THREAD];
|
||||
int offset = blockIdx.x * (BLOCK_THREADS * ITEMS_PER_THREAD);
|
||||
BlockLoadT(temp_storage.load).Load(d_in + offset, offset);
|
||||
__syncthreads();
|
||||
// Compute the block-wide prefix sum
|
||||
BlockScanT(temp_storage).Sum(thread_data);
|
||||
}
|
||||
-81
@@ -1,81 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
// CHECK: #include "hipblas.h"
|
||||
#include "cublas.h"
|
||||
#define M 6
|
||||
#define N 5
|
||||
#define IDX2C(i,j,ld) (((j)*(ld))+(i))
|
||||
static __inline__ void modify(float *m, int ldm, int n, int p, int q, float
|
||||
alpha, float beta) {
|
||||
// CHECK: hipblasSscal(n - p, alpha, &m[IDX2C(p, q, ldm)], ldm);
|
||||
// CHECK: hipblasSscal(ldm - p, beta, &m[IDX2C(p, q, ldm)], 1);
|
||||
cublasSscal(n - p, alpha, &m[IDX2C(p, q, ldm)], ldm);
|
||||
cublasSscal(ldm - p, beta, &m[IDX2C(p, q, ldm)], 1);
|
||||
}
|
||||
int main(void) {
|
||||
int i, j;
|
||||
// CHECK: hipblasStatus_t stat;
|
||||
cublasStatus stat;
|
||||
float* devPtrA;
|
||||
float* a = 0;
|
||||
a = (float *)malloc(M * N * sizeof(*a));
|
||||
if (!a) {
|
||||
printf("host memory allocation failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
for (j = 0; j < N; j++) {
|
||||
for (i = 0; i < M; i++) {
|
||||
a[IDX2C(i, j, M)] = (float)(i * M + j + 1);
|
||||
}
|
||||
}
|
||||
// cublasInit is not supported yet
|
||||
cublasInit();
|
||||
// cublasAlloc is not supported yet
|
||||
stat = cublasAlloc(M*N, sizeof(*a), (void**)&devPtrA);
|
||||
// CHECK: if (stat != HIPBLAS_STATUS_SUCCESS) {
|
||||
if (stat != CUBLAS_STATUS_SUCCESS) {
|
||||
printf("device memory allocation failed");
|
||||
// cublasShutdown is not supported yet
|
||||
cublasShutdown();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// CHECK: stat = hipblasSetMatrix(M, N, sizeof(*a), a, M, devPtrA, M);
|
||||
stat = cublasSetMatrix(M, N, sizeof(*a), a, M, devPtrA, M);
|
||||
// CHECK: if (stat != HIPBLAS_STATUS_SUCCESS) {
|
||||
if (stat != CUBLAS_STATUS_SUCCESS) {
|
||||
printf("data download failed");
|
||||
// cublasFree is not supported yet
|
||||
cublasFree(devPtrA);
|
||||
// cublasShutdown is not supported yet
|
||||
cublasShutdown();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
modify(devPtrA, M, N, 1, 2, 16.0f, 12.0f);
|
||||
// CHECK: stat = hipblasGetMatrix(M, N, sizeof(*a), devPtrA, M, a, M);
|
||||
stat = cublasGetMatrix(M, N, sizeof(*a), devPtrA, M, a, M);
|
||||
// CHECK: if (stat != HIPBLAS_STATUS_SUCCESS) {
|
||||
if (stat != CUBLAS_STATUS_SUCCESS) {
|
||||
printf("data upload failed");
|
||||
// cublasFree is not supported yet
|
||||
cublasFree(devPtrA);
|
||||
// cublasShutdown is not supported yet
|
||||
cublasShutdown();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// cublasFree is not supported yet
|
||||
cublasFree(devPtrA);
|
||||
// cublasShutdown is not supported yet
|
||||
cublasShutdown();
|
||||
for (j = 0; j < N; j++) {
|
||||
for (i = 0; i < M; i++) {
|
||||
printf("%7.0f", a[IDX2C(i, j, M)]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
free(a);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
-90
@@ -1,90 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include "hipblas.h"
|
||||
#include "cublas_v2.h"
|
||||
#define M 6
|
||||
#define N 5
|
||||
#define IDX2F(i,j,ld) ((((j)-1)*(ld))+((i)-1))
|
||||
// CHECK: static __inline__ void modify(hipblasHandle_t handle, float *m, int ldm, int
|
||||
static __inline__ void modify(cublasHandle_t handle, float *m, int ldm, int
|
||||
n, int p, int q, float alpha, float beta) {
|
||||
// CHECK: hipblasSscal(handle, n - p + 1, &alpha, &m[IDX2F(p, q, ldm)], ldm);
|
||||
// CHECK: hipblasSscal(handle, ldm - p + 1, &beta, &m[IDX2F(p, q, ldm)], 1);
|
||||
cublasSscal(handle, n - p + 1, &alpha, &m[IDX2F(p, q, ldm)], ldm);
|
||||
cublasSscal(handle, ldm - p + 1, &beta, &m[IDX2F(p, q, ldm)], 1);
|
||||
}
|
||||
int main(void) {
|
||||
// CHECK: hipError_t cudaStat;
|
||||
// CHECK: hipblasStatus_t stat;
|
||||
// CHECK: hipblasHandle_t handle;
|
||||
cudaError_t cudaStat;
|
||||
cublasStatus_t stat;
|
||||
cublasHandle_t handle;
|
||||
int i, j;
|
||||
float* devPtrA;
|
||||
float* a = 0;
|
||||
a = (float *)malloc(M * N * sizeof(*a));
|
||||
if (!a) {
|
||||
printf("host memory allocation failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
for (j = 1; j <= N; j++) {
|
||||
for (i = 1; i <= M; i++) {
|
||||
a[IDX2F(i, j, M)] = (float)((i - 1) * M + j);
|
||||
}
|
||||
}
|
||||
// CHECK: cudaStat = hipMalloc((void**)&devPtrA, M*N * sizeof(*a));
|
||||
cudaStat = cudaMalloc((void**)&devPtrA, M*N * sizeof(*a));
|
||||
// CHECK: if (cudaStat != hipSuccess) {
|
||||
if (cudaStat != cudaSuccess) {
|
||||
printf("device memory allocation failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// CHECK: stat = hipblasCreate(&handle);
|
||||
stat = cublasCreate(&handle);
|
||||
// CHECK: if (stat != HIPBLAS_STATUS_SUCCESS) {
|
||||
if (stat != CUBLAS_STATUS_SUCCESS) {
|
||||
printf("CUBLAS initialization failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// CHECK: stat = hipblasSetMatrix(M, N, sizeof(*a), a, M, devPtrA, M);
|
||||
stat = cublasSetMatrix(M, N, sizeof(*a), a, M, devPtrA, M);
|
||||
// CHECK: if (stat != HIPBLAS_STATUS_SUCCESS) {
|
||||
if (stat != CUBLAS_STATUS_SUCCESS) {
|
||||
printf("data download failed");
|
||||
// CHECK: hipFree(devPtrA);
|
||||
// CHECK: hipblasDestroy(handle);
|
||||
cudaFree(devPtrA);
|
||||
cublasDestroy(handle);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
modify(handle, devPtrA, M, N, 2, 3, 16.0f, 12.0f);
|
||||
// CHECK: stat = hipblasGetMatrix(M, N, sizeof(*a), devPtrA, M, a, M);
|
||||
stat = cublasGetMatrix(M, N, sizeof(*a), devPtrA, M, a, M);
|
||||
// CHECK: if (stat != HIPBLAS_STATUS_SUCCESS) {
|
||||
if (stat != CUBLAS_STATUS_SUCCESS) {
|
||||
printf("data upload failed");
|
||||
// CHECK: hipFree(devPtrA);
|
||||
// CHECK: hipblasDestroy(handle);
|
||||
cudaFree(devPtrA);
|
||||
cublasDestroy(handle);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// CHECK: hipFree(devPtrA);
|
||||
// CHECK: hipblasDestroy(handle);
|
||||
cudaFree(devPtrA);
|
||||
cublasDestroy(handle);
|
||||
for (j = 1; j <= N; j++) {
|
||||
for (i = 1; i <= M; i++) {
|
||||
printf("%7.0f", a[IDX2F(i, j, M)]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
free(a);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
-108
@@ -1,108 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include "hipblas.h"
|
||||
#include "cublas_v2.h"
|
||||
#define IDX2C(i,j,ld) (((j)*(ld))+(i))
|
||||
#define m 6
|
||||
#define n 4
|
||||
#define k 5
|
||||
int main(void) {
|
||||
// CHECK: hipError_t cudaStat;
|
||||
// CHECK: hipblasStatus_t stat;
|
||||
// CHECK: hipblasHandle_t handle;
|
||||
cudaError_t cudaStat;
|
||||
cublasStatus_t stat;
|
||||
cublasHandle_t handle;
|
||||
int i, j;
|
||||
float * a;
|
||||
float * b;
|
||||
float * c;
|
||||
a = (float *)malloc(m*k * sizeof(float));
|
||||
b = (float *)malloc(k*n * sizeof(float));
|
||||
c = (float *)malloc(m*n * sizeof(float));
|
||||
int ind = 11;
|
||||
for (j = 0; j<k; j++) {
|
||||
for (i = 0; i<m; i++) {
|
||||
a[IDX2C(i, j, m)] = (float)ind++;
|
||||
}
|
||||
}
|
||||
printf("a:\n");
|
||||
for (i = 0; i<m; i++) {
|
||||
for (j = 0; j<k; j++) {
|
||||
printf(" %5.0f", a[IDX2C(i, j, m)]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
ind = 11;
|
||||
for (j = 0; j<n; j++) {
|
||||
for (i = 0; i<k; i++) {
|
||||
b[IDX2C(i, j, k)] = (float)ind++;
|
||||
}
|
||||
}
|
||||
printf("b:\n");
|
||||
for (i = 0; i<k; i++) {
|
||||
for (j = 0; j<n; j++) {
|
||||
printf(" %5.0f", b[IDX2C(i, j, k)]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
ind = 11;
|
||||
for (j = 0; j<n; j++) {
|
||||
for (i = 0; i<m; i++) {
|
||||
c[IDX2C(i, j, m)] = (float)ind++;
|
||||
}
|
||||
}
|
||||
printf("c:\n");
|
||||
for (i = 0; i<m; i++) {
|
||||
for (j = 0; j<n; j++) {
|
||||
printf(" %5.0f", c[IDX2C(i, j, m)]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
float * d_a;
|
||||
float * d_b;
|
||||
float * d_c;
|
||||
// CHECK: cudaStat = hipMalloc((void **)& d_a, m*k * sizeof(*a));
|
||||
// CHECK: cudaStat = hipMalloc((void **)& d_b, k*n * sizeof(*b));
|
||||
// CHECK: cudaStat = hipMalloc((void **)& d_c, m*n * sizeof(*c));
|
||||
cudaStat = cudaMalloc((void **)& d_a, m*k * sizeof(*a));
|
||||
cudaStat = cudaMalloc((void **)& d_b, k*n * sizeof(*b));
|
||||
cudaStat = cudaMalloc((void **)& d_c, m*n * sizeof(*c));
|
||||
// CHECK: stat = hipblasCreate(&handle);
|
||||
stat = cublasCreate(&handle);
|
||||
// CHECK: stat = hipblasSetMatrix(m, k, sizeof(*a), a, m, d_a, m);
|
||||
// CHECK: stat = hipblasSetMatrix(k, n, sizeof(*b), b, k, d_b, k);
|
||||
// CHECK: stat = hipblasSetMatrix(m, n, sizeof(*c), c, m, d_c, m);
|
||||
stat = cublasSetMatrix(m, k, sizeof(*a), a, m, d_a, m);
|
||||
stat = cublasSetMatrix(k, n, sizeof(*b), b, k, d_b, k);
|
||||
stat = cublasSetMatrix(m, n, sizeof(*c), c, m, d_c, m);
|
||||
float al = 1.0f;
|
||||
float bet = 1.0f;
|
||||
// CHECK: stat = hipblasSgemm(handle, HIPBLAS_OP_N, HIPBLAS_OP_N, m, n, k, &al, d_a, m, d_b, k, &bet, d_c, m);
|
||||
stat = cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N, m, n, k, &al, d_a, m, d_b, k, &bet, d_c, m);
|
||||
// CHECK: stat = hipblasGetMatrix(m, n, sizeof(*c), d_c, m, c, m);
|
||||
stat = cublasGetMatrix(m, n, sizeof(*c), d_c, m, c, m);
|
||||
printf("c after Sgemm :\n");
|
||||
for (i = 0; i<m; i++) {
|
||||
for (j = 0; j<n; j++) {
|
||||
printf(" %7.0f", c[IDX2C(i, j, m)]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
// CHECK: hipFree(d_a);
|
||||
// CHECK: hipFree(d_b);
|
||||
// CHECK: hipFree(d_c);
|
||||
// CHECK: hipblasDestroy(handle);
|
||||
cudaFree(d_a);
|
||||
cudaFree(d_b);
|
||||
cudaFree(d_c);
|
||||
cublasDestroy(handle);
|
||||
free(a);
|
||||
free(b);
|
||||
free(c);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
-81
@@ -1,81 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args "-roc" %clang_args
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
// CHECK: #include "rocblas.h"
|
||||
#include "cublas.h"
|
||||
#define M 6
|
||||
#define N 5
|
||||
#define IDX2C(i,j,ld) (((j)*(ld))+(i))
|
||||
static __inline__ void modify(float *m, int ldm, int n, int p, int q, float
|
||||
alpha, float beta) {
|
||||
// CHECK: rocblas_sscal(n - p, alpha, &m[IDX2C(p, q, ldm)], ldm);
|
||||
// CHECK: rocblas_sscal(ldm - p, beta, &m[IDX2C(p, q, ldm)], 1);
|
||||
cublasSscal(n - p, alpha, &m[IDX2C(p, q, ldm)], ldm);
|
||||
cublasSscal(ldm - p, beta, &m[IDX2C(p, q, ldm)], 1);
|
||||
}
|
||||
int main(void) {
|
||||
int i, j;
|
||||
// CHECK: rocblas_status stat;
|
||||
cublasStatus stat;
|
||||
float* devPtrA;
|
||||
float* a = 0;
|
||||
a = (float *)malloc(M * N * sizeof(*a));
|
||||
if (!a) {
|
||||
printf("host memory allocation failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
for (j = 0; j < N; j++) {
|
||||
for (i = 0; i < M; i++) {
|
||||
a[IDX2C(i, j, M)] = (float)(i * M + j + 1);
|
||||
}
|
||||
}
|
||||
// cublasInit is not supported yet
|
||||
cublasInit();
|
||||
// cublasAlloc is not supported yet
|
||||
stat = cublasAlloc(M*N, sizeof(*a), (void**)&devPtrA);
|
||||
// CHECK: if (stat != rocblas_status_success) {
|
||||
if (stat != CUBLAS_STATUS_SUCCESS) {
|
||||
printf("device memory allocation failed");
|
||||
// cublasShutdown is not supported yet
|
||||
cublasShutdown();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// CHECK: stat = rocblas_set_matrix(M, N, sizeof(*a), a, M, devPtrA, M);
|
||||
stat = cublasSetMatrix(M, N, sizeof(*a), a, M, devPtrA, M);
|
||||
// CHECK: if (stat != rocblas_status_success) {
|
||||
if (stat != CUBLAS_STATUS_SUCCESS) {
|
||||
printf("data download failed");
|
||||
// cublasFree is not supported yet
|
||||
cublasFree(devPtrA);
|
||||
// cublasShutdown is not supported yet
|
||||
cublasShutdown();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
modify(devPtrA, M, N, 1, 2, 16.0f, 12.0f);
|
||||
// CHECK: stat = rocblas_get_matrix(M, N, sizeof(*a), devPtrA, M, a, M);
|
||||
stat = cublasGetMatrix(M, N, sizeof(*a), devPtrA, M, a, M);
|
||||
// CHECK: if (stat != rocblas_status_success) {
|
||||
if (stat != CUBLAS_STATUS_SUCCESS) {
|
||||
printf("data upload failed");
|
||||
// cublasFree is not supported yet
|
||||
cublasFree(devPtrA);
|
||||
// cublasShutdown is not supported yet
|
||||
cublasShutdown();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// cublasFree is not supported yet
|
||||
cublasFree(devPtrA);
|
||||
// cublasShutdown is not supported yet
|
||||
cublasShutdown();
|
||||
for (j = 0; j < N; j++) {
|
||||
for (i = 0; i < M; i++) {
|
||||
printf("%7.0f", a[IDX2C(i, j, M)]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
free(a);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
-90
@@ -1,90 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args "-roc" %clang_args
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include "rocblas.h"
|
||||
#include "cublas_v2.h"
|
||||
#define M 6
|
||||
#define N 5
|
||||
#define IDX2F(i,j,ld) ((((j)-1)*(ld))+((i)-1))
|
||||
// CHECK: static __inline__ void modify(rocblas_handle handle, float *m, int ldm, int
|
||||
static __inline__ void modify(cublasHandle_t handle, float *m, int ldm, int
|
||||
n, int p, int q, float alpha, float beta) {
|
||||
// CHECK: rocblas_sscal(handle, n - p + 1, &alpha, &m[IDX2F(p, q, ldm)], ldm);
|
||||
// CHECK: rocblas_sscal(handle, ldm - p + 1, &beta, &m[IDX2F(p, q, ldm)], 1);
|
||||
cublasSscal(handle, n - p + 1, &alpha, &m[IDX2F(p, q, ldm)], ldm);
|
||||
cublasSscal(handle, ldm - p + 1, &beta, &m[IDX2F(p, q, ldm)], 1);
|
||||
}
|
||||
int main(void) {
|
||||
// CHECK: hipError_t cudaStat;
|
||||
// CHECK: rocblas_status stat;
|
||||
// CHECK: rocblas_handle handle;
|
||||
cudaError_t cudaStat;
|
||||
cublasStatus_t stat;
|
||||
cublasHandle_t handle;
|
||||
int i, j;
|
||||
float* devPtrA;
|
||||
float* a = 0;
|
||||
a = (float *)malloc(M * N * sizeof(*a));
|
||||
if (!a) {
|
||||
printf("host memory allocation failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
for (j = 1; j <= N; j++) {
|
||||
for (i = 1; i <= M; i++) {
|
||||
a[IDX2F(i, j, M)] = (float)((i - 1) * M + j);
|
||||
}
|
||||
}
|
||||
// CHECK: cudaStat = hipMalloc((void**)&devPtrA, M*N * sizeof(*a));
|
||||
cudaStat = cudaMalloc((void**)&devPtrA, M*N * sizeof(*a));
|
||||
// CHECK: if (cudaStat != hipSuccess) {
|
||||
if (cudaStat != cudaSuccess) {
|
||||
printf("device memory allocation failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// CHECK: stat = rocblas_create_handle(&handle);
|
||||
stat = cublasCreate(&handle);
|
||||
// CHECK: if (stat != rocblas_status_success) {
|
||||
if (stat != CUBLAS_STATUS_SUCCESS) {
|
||||
printf("CUBLAS initialization failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// CHECK: stat = rocblas_set_matrix(M, N, sizeof(*a), a, M, devPtrA, M);
|
||||
stat = cublasSetMatrix(M, N, sizeof(*a), a, M, devPtrA, M);
|
||||
// CHECK: if (stat != rocblas_status_success) {
|
||||
if (stat != CUBLAS_STATUS_SUCCESS) {
|
||||
printf("data download failed");
|
||||
// CHECK: hipFree(devPtrA);
|
||||
// CHECK: rocblas_destroy_handle(handle);
|
||||
cudaFree(devPtrA);
|
||||
cublasDestroy(handle);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
modify(handle, devPtrA, M, N, 2, 3, 16.0f, 12.0f);
|
||||
// CHECK: stat = rocblas_get_matrix(M, N, sizeof(*a), devPtrA, M, a, M);
|
||||
stat = cublasGetMatrix(M, N, sizeof(*a), devPtrA, M, a, M);
|
||||
// CHECK: if (stat != rocblas_status_success) {
|
||||
if (stat != CUBLAS_STATUS_SUCCESS) {
|
||||
printf("data upload failed");
|
||||
// CHECK: hipFree(devPtrA);
|
||||
// CHECK: rocblas_destroy_handle(handle);
|
||||
cudaFree(devPtrA);
|
||||
cublasDestroy(handle);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// CHECK: hipFree(devPtrA);
|
||||
// CHECK: rocblas_destroy_handle(handle);
|
||||
cudaFree(devPtrA);
|
||||
cublasDestroy(handle);
|
||||
for (j = 1; j <= N; j++) {
|
||||
for (i = 1; i <= M; i++) {
|
||||
printf("%7.0f", a[IDX2F(i, j, M)]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
free(a);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
-108
@@ -1,108 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args "-roc" %clang_args
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include "rocblas.h"
|
||||
#include "cublas_v2.h"
|
||||
#define IDX2C(i,j,ld) (((j)*(ld))+(i))
|
||||
#define m 6
|
||||
#define n 4
|
||||
#define k 5
|
||||
int main(void) {
|
||||
// CHECK: hipError_t cudaStat;
|
||||
// CHECK: rocblas_status stat;
|
||||
// CHECK: rocblas_handle handle;
|
||||
cudaError_t cudaStat;
|
||||
cublasStatus_t stat;
|
||||
cublasHandle_t handle;
|
||||
int i, j;
|
||||
float * a;
|
||||
float * b;
|
||||
float * c;
|
||||
a = (float *)malloc(m*k * sizeof(float));
|
||||
b = (float *)malloc(k*n * sizeof(float));
|
||||
c = (float *)malloc(m*n * sizeof(float));
|
||||
int ind = 11;
|
||||
for (j = 0; j<k; j++) {
|
||||
for (i = 0; i<m; i++) {
|
||||
a[IDX2C(i, j, m)] = (float)ind++;
|
||||
}
|
||||
}
|
||||
printf("a:\n");
|
||||
for (i = 0; i<m; i++) {
|
||||
for (j = 0; j<k; j++) {
|
||||
printf(" %5.0f", a[IDX2C(i, j, m)]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
ind = 11;
|
||||
for (j = 0; j<n; j++) {
|
||||
for (i = 0; i<k; i++) {
|
||||
b[IDX2C(i, j, k)] = (float)ind++;
|
||||
}
|
||||
}
|
||||
printf("b:\n");
|
||||
for (i = 0; i<k; i++) {
|
||||
for (j = 0; j<n; j++) {
|
||||
printf(" %5.0f", b[IDX2C(i, j, k)]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
ind = 11;
|
||||
for (j = 0; j<n; j++) {
|
||||
for (i = 0; i<m; i++) {
|
||||
c[IDX2C(i, j, m)] = (float)ind++;
|
||||
}
|
||||
}
|
||||
printf("c:\n");
|
||||
for (i = 0; i<m; i++) {
|
||||
for (j = 0; j<n; j++) {
|
||||
printf(" %5.0f", c[IDX2C(i, j, m)]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
float * d_a;
|
||||
float * d_b;
|
||||
float * d_c;
|
||||
// CHECK: cudaStat = hipMalloc((void **)& d_a, m*k * sizeof(*a));
|
||||
// CHECK: cudaStat = hipMalloc((void **)& d_b, k*n * sizeof(*b));
|
||||
// CHECK: cudaStat = hipMalloc((void **)& d_c, m*n * sizeof(*c));
|
||||
cudaStat = cudaMalloc((void **)& d_a, m*k * sizeof(*a));
|
||||
cudaStat = cudaMalloc((void **)& d_b, k*n * sizeof(*b));
|
||||
cudaStat = cudaMalloc((void **)& d_c, m*n * sizeof(*c));
|
||||
// CHECK: stat = rocblas_create_handle(&handle);
|
||||
stat = cublasCreate(&handle);
|
||||
// CHECK: stat = rocblas_set_matrix(m, k, sizeof(*a), a, m, d_a, m);
|
||||
// CHECK: stat = rocblas_set_matrix(k, n, sizeof(*b), b, k, d_b, k);
|
||||
// CHECK: stat = rocblas_set_matrix(m, n, sizeof(*c), c, m, d_c, m);
|
||||
stat = cublasSetMatrix(m, k, sizeof(*a), a, m, d_a, m);
|
||||
stat = cublasSetMatrix(k, n, sizeof(*b), b, k, d_b, k);
|
||||
stat = cublasSetMatrix(m, n, sizeof(*c), c, m, d_c, m);
|
||||
float al = 1.0f;
|
||||
float bet = 1.0f;
|
||||
// CHECK: stat = rocblas_sgemm(handle, rocblas_operation_none, rocblas_operation_none, m, n, k, &al, d_a, m, d_b, k, &bet, d_c, m);
|
||||
stat = cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N, m, n, k, &al, d_a, m, d_b, k, &bet, d_c, m);
|
||||
// CHECK: stat = rocblas_get_matrix(m, n, sizeof(*c), d_c, m, c, m);
|
||||
stat = cublasGetMatrix(m, n, sizeof(*c), d_c, m, c, m);
|
||||
printf("c after Sgemm :\n");
|
||||
for (i = 0; i<m; i++) {
|
||||
for (j = 0; j<n; j++) {
|
||||
printf(" %7.0f", c[IDX2C(i, j, m)]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
// CHECK: hipFree(d_a);
|
||||
// CHECK: hipFree(d_b);
|
||||
// CHECK: hipFree(d_c);
|
||||
// CHECK: rocblas_destroy_handle(handle);
|
||||
cudaFree(d_a);
|
||||
cudaFree(d_b);
|
||||
cudaFree(d_c);
|
||||
cublasDestroy(handle);
|
||||
free(a);
|
||||
free(b);
|
||||
free(c);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args "--skip-excluded-preprocessor-conditional-blocks" %clang_args
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
// CHECK: #include "hip/hip_complex.h"
|
||||
#include "cuComplex.h"
|
||||
|
||||
#define TYPEFLOAT
|
||||
#define DIMX 100
|
||||
#define DIMY 40
|
||||
#define moveX 2
|
||||
#define moveY 1
|
||||
|
||||
#define MAXITERATIONS 10
|
||||
|
||||
#ifdef TYPEFLOAT
|
||||
#define TYPE float
|
||||
// CHECK: #define cTYPE hipFloatComplex
|
||||
#define cTYPE cuFloatComplex
|
||||
// CHECK: #define cMakecuComplex(re,i) make_hipFloatComplex(re,i)
|
||||
#define cMakecuComplex(re,i) make_cuFloatComplex(re,i)
|
||||
#endif
|
||||
#ifdef TYPEDOUBLE
|
||||
// CHECK: #define TYPE hipDoubleComplex
|
||||
#define TYPE cuDoubleComplex
|
||||
// CHECK: #define cMakecuComplex(re,i) make_hipDoubleComplex(re,i)
|
||||
#define cMakecuComplex(re,i) make_cuDoubleComplex(re,i)
|
||||
#endif
|
||||
|
||||
__device__ cTYPE juliaFunctor(cTYPE p, cTYPE c) {
|
||||
// CHECK: return hipCaddf(hipCmulf(p, p), c);
|
||||
return cuCaddf(cuCmulf(p, p), c);
|
||||
}
|
||||
|
||||
__device__ cTYPE convertToComplex(int x, int y, float zoom) {
|
||||
TYPE jx = 1.5 * (x - DIMX / 2) / (0.5 * zoom * DIMX) + moveX;
|
||||
TYPE jy = (y - DIMY / 2) / (0.5 * zoom * DIMY) + moveY;
|
||||
return cMakecuComplex(jx, jy);
|
||||
}
|
||||
|
||||
__device__ int evolveComplexPoint(cTYPE p, cTYPE c) {
|
||||
int it = 1;
|
||||
// CHECK: while (it <= MAXITERATIONS && hipCabsf(p) <= 4) {
|
||||
while (it <= MAXITERATIONS && cuCabsf(p) <= 4) {
|
||||
p = juliaFunctor(p, c);
|
||||
it++;
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
__global__ void computeJulia(int* data, cTYPE c, float zoom) {
|
||||
int i = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int j = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
|
||||
if (i<DIMX && j<DIMY) {
|
||||
cTYPE p = convertToComplex(i, j, zoom);
|
||||
data[i*DIMY + j] = evolveComplexPoint(p, c);
|
||||
}
|
||||
}
|
||||
-267
@@ -1,267 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda.h>
|
||||
// CHECK: #include "hipDNN.h"
|
||||
#include "cudnn.h"
|
||||
|
||||
// CHECK: hipError_t err = (f); \
|
||||
// CHECK: if (err != hipSuccess) { \
|
||||
|
||||
#define CUDA_CALL(f) { \
|
||||
cudaError_t err = (f); \
|
||||
if (err != cudaSuccess) { \
|
||||
std::cout \
|
||||
<< " Error occurred: " << err << std::endl; \
|
||||
std::exit(1); \
|
||||
} \
|
||||
}
|
||||
// CHECK: hipdnnStatus_t err = (f); \
|
||||
// CHECK: if (err != HIPDNN_STATUS_SUCCESS) { \
|
||||
|
||||
#define CUDNN_CALL(f) { \
|
||||
cudnnStatus_t err = (f); \
|
||||
if (err != CUDNN_STATUS_SUCCESS) { \
|
||||
std::cout \
|
||||
<< " Error occurred: " << err << std::endl; \
|
||||
std::exit(1); \
|
||||
} \
|
||||
}
|
||||
|
||||
__global__ void dev_const(float *px, float k) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
px[tid] = k;
|
||||
}
|
||||
|
||||
__global__ void dev_iota(float *px) {
|
||||
int tid = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
px[tid] = tid;
|
||||
}
|
||||
|
||||
void print(const float *data, int n, int c, int h, int w) {
|
||||
std::vector<float> buffer(1 << 20);
|
||||
// CHECK: CUDA_CALL(hipMemcpy(
|
||||
CUDA_CALL(cudaMemcpy(
|
||||
buffer.data(), data,
|
||||
n * c * h * w * sizeof(float),
|
||||
// CHECK: hipMemcpyDeviceToHost));
|
||||
cudaMemcpyDeviceToHost));
|
||||
int a = 0;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
for (int j = 0; j < c; ++j) {
|
||||
std::cout << "n=" << i << ", c=" << j << ":" << std::endl;
|
||||
for (int k = 0; k < h; ++k) {
|
||||
for (int l = 0; l < w; ++l) {
|
||||
std::cout << std::setw(4) << std::right << buffer[a];
|
||||
++a;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
// CHECK: hipdnnHandle_t cudnn;
|
||||
cudnnHandle_t cudnn;
|
||||
// CHECK: CUDNN_CALL(hipdnnCreate(&cudnn));
|
||||
CUDNN_CALL(cudnnCreate(&cudnn));
|
||||
|
||||
// input
|
||||
const int in_n = 1;
|
||||
const int in_c = 1;
|
||||
const int in_h = 5;
|
||||
const int in_w = 5;
|
||||
std::cout << "in_n: " << in_n << std::endl;
|
||||
std::cout << "in_c: " << in_c << std::endl;
|
||||
std::cout << "in_h: " << in_h << std::endl;
|
||||
std::cout << "in_w: " << in_w << std::endl;
|
||||
std::cout << std::endl;
|
||||
// CHECK: hipdnnTensorDescriptor_t in_desc;
|
||||
cudnnTensorDescriptor_t in_desc;
|
||||
// CHECK: CUDNN_CALL(hipdnnCreateTensorDescriptor(&in_desc));
|
||||
CUDNN_CALL(cudnnCreateTensorDescriptor(&in_desc));
|
||||
// CHECK: CUDNN_CALL(hipdnnSetTensor4dDescriptor(
|
||||
CUDNN_CALL(cudnnSetTensor4dDescriptor(
|
||||
// CHECK: in_desc, HIPDNN_TENSOR_NCHW, HIPDNN_DATA_FLOAT,
|
||||
in_desc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT,
|
||||
in_n, in_c, in_h, in_w));
|
||||
|
||||
float *in_data;
|
||||
// CHECK: CUDA_CALL(hipMalloc(
|
||||
CUDA_CALL(cudaMalloc(
|
||||
&in_data, in_n * in_c * in_h * in_w * sizeof(float)));
|
||||
|
||||
// filter
|
||||
const int filt_k = 1;
|
||||
const int filt_c = 1;
|
||||
const int filt_h = 2;
|
||||
const int filt_w = 2;
|
||||
std::cout << "filt_k: " << filt_k << std::endl;
|
||||
std::cout << "filt_c: " << filt_c << std::endl;
|
||||
std::cout << "filt_h: " << filt_h << std::endl;
|
||||
std::cout << "filt_w: " << filt_w << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
// CHECK: hipdnnFilterDescriptor_t filt_desc;
|
||||
cudnnFilterDescriptor_t filt_desc;
|
||||
// CHECK: CUDNN_CALL(hipdnnCreateFilterDescriptor(&filt_desc));
|
||||
CUDNN_CALL(cudnnCreateFilterDescriptor(&filt_desc));
|
||||
// CHECK: CUDNN_CALL(hipdnnSetFilter4dDescriptor(
|
||||
CUDNN_CALL(cudnnSetFilter4dDescriptor(
|
||||
// CHECK: filt_desc, HIPDNN_DATA_FLOAT, HIPDNN_TENSOR_NCHW,
|
||||
filt_desc, CUDNN_DATA_FLOAT, CUDNN_TENSOR_NCHW,
|
||||
filt_k, filt_c, filt_h, filt_w));
|
||||
|
||||
float *filt_data;
|
||||
// CUDA_CALL(hipMalloc(
|
||||
CUDA_CALL(cudaMalloc(
|
||||
&filt_data, filt_k * filt_c * filt_h * filt_w * sizeof(float)));
|
||||
|
||||
// convolution
|
||||
const int pad_h = 1;
|
||||
const int pad_w = 1;
|
||||
const int str_h = 1;
|
||||
const int str_w = 1;
|
||||
const int dil_h = 1;
|
||||
const int dil_w = 1;
|
||||
std::cout << "pad_h: " << pad_h << std::endl;
|
||||
std::cout << "pad_w: " << pad_w << std::endl;
|
||||
std::cout << "str_h: " << str_h << std::endl;
|
||||
std::cout << "str_w: " << str_w << std::endl;
|
||||
std::cout << "dil_h: " << dil_h << std::endl;
|
||||
std::cout << "dil_w: " << dil_w << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
// CHECK: hipdnnConvolutionDescriptor_t conv_desc;
|
||||
cudnnConvolutionDescriptor_t conv_desc;
|
||||
// CUDNN_CALL(hipdnnCreateConvolutionDescriptor(&conv_desc));
|
||||
CUDNN_CALL(cudnnCreateConvolutionDescriptor(&conv_desc));
|
||||
// CHECK: CUDNN_CALL(hipdnnSetConvolution2dDescriptor(
|
||||
CUDNN_CALL(cudnnSetConvolution2dDescriptor(
|
||||
conv_desc,
|
||||
pad_h, pad_w, str_h, str_w, dil_h, dil_w,
|
||||
// CHECK: HIPDNN_CONVOLUTION, HIPDNN_DATA_FLOAT));
|
||||
CUDNN_CONVOLUTION, CUDNN_DATA_FLOAT));
|
||||
|
||||
// output
|
||||
int out_n;
|
||||
int out_c;
|
||||
int out_h;
|
||||
int out_w;
|
||||
|
||||
// CHECK: CUDNN_CALL(hipdnnGetConvolution2dForwardOutputDim(
|
||||
CUDNN_CALL(cudnnGetConvolution2dForwardOutputDim(
|
||||
conv_desc, in_desc, filt_desc,
|
||||
&out_n, &out_c, &out_h, &out_w));
|
||||
|
||||
std::cout << "out_n: " << out_n << std::endl;
|
||||
std::cout << "out_c: " << out_c << std::endl;
|
||||
std::cout << "out_h: " << out_h << std::endl;
|
||||
std::cout << "out_w: " << out_w << std::endl;
|
||||
std::cout << std::endl;
|
||||
// CHECK: hipdnnTensorDescriptor_t out_desc;
|
||||
cudnnTensorDescriptor_t out_desc;
|
||||
// CHECK: CUDNN_CALL(hipdnnCreateTensorDescriptor(&out_desc));
|
||||
CUDNN_CALL(cudnnCreateTensorDescriptor(&out_desc));
|
||||
// CHECK: CUDNN_CALL(hipdnnSetTensor4dDescriptor(
|
||||
CUDNN_CALL(cudnnSetTensor4dDescriptor(
|
||||
// CHECK: out_desc, HIPDNN_TENSOR_NCHW, HIPDNN_DATA_FLOAT,
|
||||
out_desc, CUDNN_TENSOR_NCHW, CUDNN_DATA_FLOAT,
|
||||
out_n, out_c, out_h, out_w));
|
||||
|
||||
|
||||
cudnnDataType_t *dataType = nullptr;
|
||||
cudnnTensorFormat_t *tensorFormat = nullptr;
|
||||
int *p_filt_k = nullptr;
|
||||
int *p_filt_c = nullptr;
|
||||
int *p_filt_h = nullptr;
|
||||
int *p_filt_w = nullptr;
|
||||
|
||||
// CHECK: CUDNN_CALL(hipdnnGetFilter4dDescriptor(
|
||||
CUDNN_CALL(cudnnGetFilter4dDescriptor(
|
||||
filt_desc, dataType, tensorFormat,
|
||||
p_filt_k, p_filt_c, p_filt_h, p_filt_w));
|
||||
|
||||
float *out_data;
|
||||
// CHECK: CUDA_CALL(hipMalloc(
|
||||
CUDA_CALL(cudaMalloc(
|
||||
&out_data, out_n * out_c * out_h * out_w * sizeof(float)));
|
||||
|
||||
// algorithm
|
||||
// CHECK: hipdnnConvolutionFwdAlgo_t algo;
|
||||
cudnnConvolutionFwdAlgo_t algo;
|
||||
// CHECK: CUDNN_CALL(hipdnnGetConvolutionForwardAlgorithm(
|
||||
CUDNN_CALL(cudnnGetConvolutionForwardAlgorithm(
|
||||
cudnn,
|
||||
in_desc, filt_desc, conv_desc, out_desc,
|
||||
// CHECK: HIPDNN_CONVOLUTION_FWD_PREFER_FASTEST, 0, &algo));
|
||||
CUDNN_CONVOLUTION_FWD_PREFER_FASTEST, 0, &algo));
|
||||
|
||||
std::cout << "Convolution algorithm: " << algo << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
// workspace
|
||||
size_t ws_size;
|
||||
// CHECK: CUDNN_CALL(hipdnnGetConvolutionForwardWorkspaceSize(
|
||||
CUDNN_CALL(cudnnGetConvolutionForwardWorkspaceSize(
|
||||
cudnn, in_desc, filt_desc, conv_desc, out_desc, algo, &ws_size));
|
||||
|
||||
float *ws_data;
|
||||
// CHECK: CUDA_CALL(hipMalloc(&ws_data, ws_size));
|
||||
CUDA_CALL(cudaMalloc(&ws_data, ws_size));
|
||||
|
||||
std::cout << "Workspace size: " << ws_size << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
// perform
|
||||
float alpha = 1.f;
|
||||
float beta = 0.f;
|
||||
// CHECK: hipLaunchKernelGGL(dev_iota, dim3(in_w * in_h), dim3(in_n * in_c), 0, 0, in_data);
|
||||
// CHECK: hipLaunchKernelGGL(dev_const, dim3(filt_w * filt_h), dim3(filt_k * filt_c), 0, 0, filt_data, 1.f);
|
||||
dev_iota<<<in_w * in_h, in_n * in_c>>>(in_data);
|
||||
dev_const<<<filt_w * filt_h, filt_k * filt_c>>>(filt_data, 1.f);
|
||||
// CHECK: CUDNN_CALL(hipdnnConvolutionForward(
|
||||
CUDNN_CALL(cudnnConvolutionForward(
|
||||
cudnn,
|
||||
&alpha, in_desc, in_data, filt_desc, filt_data,
|
||||
conv_desc, algo, ws_data, ws_size,
|
||||
&beta, out_desc, out_data));
|
||||
|
||||
// results
|
||||
std::cout << "in_data:" << std::endl;
|
||||
print(in_data, in_n, in_c, in_h, in_w);
|
||||
|
||||
std::cout << "filt_data:" << std::endl;
|
||||
print(filt_data, filt_k, filt_c, filt_h, filt_w);
|
||||
|
||||
std::cout << "out_data:" << std::endl;
|
||||
print(out_data, out_n, out_c, out_h, out_w);
|
||||
|
||||
// finalizing
|
||||
// CHECK: CUDA_CALL(hipFree(ws_data));
|
||||
CUDA_CALL(cudaFree(ws_data));
|
||||
// CHECK: CUDA_CALL(hipFree(out_data));
|
||||
CUDA_CALL(cudaFree(out_data));
|
||||
// CHECK: CUDNN_CALL(hipdnnDestroyTensorDescriptor(out_desc));
|
||||
CUDNN_CALL(cudnnDestroyTensorDescriptor(out_desc));
|
||||
// CHECK: CUDNN_CALL(hipdnnDestroyConvolutionDescriptor(conv_desc));
|
||||
CUDNN_CALL(cudnnDestroyConvolutionDescriptor(conv_desc));
|
||||
// CHECK: CUDA_CALL(hipFree(filt_data));
|
||||
CUDA_CALL(cudaFree(filt_data));
|
||||
// CHECK: CUDNN_CALL(hipdnnDestroyFilterDescriptor(filt_desc));
|
||||
CUDNN_CALL(cudnnDestroyFilterDescriptor(filt_desc));
|
||||
// CHECK: CUDA_CALL(hipFree(in_data));
|
||||
CUDA_CALL(cudaFree(in_data));
|
||||
// CHECK: CUDNN_CALL(hipdnnDestroyTensorDescriptor(in_desc));
|
||||
CUDNN_CALL(cudnnDestroyTensorDescriptor(in_desc));
|
||||
// CHECK: CUDNN_CALL(hipdnnDestroy(cudnn));
|
||||
CUDNN_CALL(cudnnDestroy(cudnn));
|
||||
return 0;
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <stdio.h>
|
||||
// CHECK: #include <hipDNN.h>
|
||||
#include <cudnn.h>
|
||||
|
||||
/**
|
||||
*
|
||||
* Author: Jon Gauthier <jon@gauthiers.net>
|
||||
* February 2015
|
||||
*
|
||||
. * Adopted for CUDA/CUDNN 9.0
|
||||
*/
|
||||
|
||||
void printMatrix(const double *mat, int m, int n) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
for (int i = 0; i < m; i++) {
|
||||
printf("%f\n", mat[j * m + i]);
|
||||
}
|
||||
printf("\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
double *makeDiffData(int m, int c) {
|
||||
double *diff = (double *) calloc(m * c, sizeof(double));
|
||||
for (int j = 0; j < m; j++) {
|
||||
int class_ = rand() % c;
|
||||
printf("%d class: %d\n", j, class_);
|
||||
for (int i = 0; i < c; i++)
|
||||
diff[j * c + i] = class_ == i ? -c / (double) m : 0;
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int m = 5, c = 4, numChannels = 1;
|
||||
|
||||
double *fcLayer = (double *) malloc(m * c * sizeof(double));
|
||||
for (int i = 0; i < m; i++) {
|
||||
double def = rand() % 25;
|
||||
for (int c_idx = 0; c_idx < c; c_idx++) {
|
||||
int offset = i * c + c_idx;
|
||||
fcLayer[offset] = def;
|
||||
}
|
||||
}
|
||||
printf("FC LAYER:\n");
|
||||
printMatrix(fcLayer, c, m);
|
||||
|
||||
double *d_fcLayer;
|
||||
// CHECK: hipMalloc((void**) &d_fcLayer, m * c * sizeof(double));
|
||||
cudaMalloc((void**) &d_fcLayer, m * c * sizeof(double));
|
||||
// CHECK: hipMemcpy(d_fcLayer, fcLayer, m * c * sizeof(double), hipMemcpyHostToDevice);
|
||||
cudaMemcpy(d_fcLayer, fcLayer, m * c * sizeof(double), cudaMemcpyHostToDevice);
|
||||
|
||||
double *d_softmaxData;
|
||||
// CHECK: hipMalloc((void**) &d_softmaxData, m * c * sizeof(double));
|
||||
cudaMalloc((void**) &d_softmaxData, m * c * sizeof(double));
|
||||
|
||||
// CHECK: hipdnnHandle_t handle;
|
||||
cudnnHandle_t handle;
|
||||
// CHECK: hipdnnCreate(&handle);
|
||||
cudnnCreate(&handle);
|
||||
|
||||
float one = 1;
|
||||
float zero = 0;
|
||||
|
||||
// softmaxForward(n, c, h, w, dstData, &srcData);
|
||||
// CHECK: hipdnnTensorDescriptor_t srcTensorDesc, sftTensorDesc;
|
||||
// CHECK: hipdnnCreateTensorDescriptor(&srcTensorDesc);
|
||||
// CHECK: hipdnnCreateTensorDescriptor(&sftTensorDesc);
|
||||
cudnnTensorDescriptor_t srcTensorDesc, sftTensorDesc;
|
||||
cudnnCreateTensorDescriptor(&srcTensorDesc);
|
||||
cudnnCreateTensorDescriptor(&sftTensorDesc);
|
||||
// CHECK: hipdnnSetTensor4dDescriptor(srcTensorDesc, HIPDNN_TENSOR_NCHW, HIPDNN_DATA_DOUBLE,
|
||||
cudnnSetTensor4dDescriptor(srcTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_DOUBLE,
|
||||
m, c, 1, 1);
|
||||
// CHECK: hipdnnSetTensor4dDescriptor(sftTensorDesc, HIPDNN_TENSOR_NCHW, HIPDNN_DATA_DOUBLE,
|
||||
cudnnSetTensor4dDescriptor(sftTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_DOUBLE,
|
||||
m, c, 1, 1);
|
||||
// CHECK: hipdnnSoftmaxForward(handle, HIPDNN_SOFTMAX_ACCURATE, HIPDNN_SOFTMAX_MODE_CHANNEL, &one,
|
||||
cudnnSoftmaxForward(handle, CUDNN_SOFTMAX_ACCURATE, CUDNN_SOFTMAX_MODE_CHANNEL, &one,
|
||||
srcTensorDesc, d_fcLayer, &zero, sftTensorDesc, d_softmaxData);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
// Copy back
|
||||
double *result = (double *) malloc(m * c * sizeof(double));
|
||||
// CHECK: hipMemcpy(result, d_softmaxData, m * c * sizeof(double), hipMemcpyDeviceToHost);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaMemcpy(result, d_softmaxData, m * c * sizeof(double), cudaMemcpyDeviceToHost);
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
// Log
|
||||
printf("SOFTMAX:\n");
|
||||
printMatrix(result, c, m);
|
||||
|
||||
// Try backward
|
||||
// CHECK: hipdnnTensorDescriptor_t diffTensorDesc;
|
||||
// CHECK: hipdnnCreateTensorDescriptor(&diffTensorDesc);
|
||||
// CHECK: hipdnnSetTensor4dDescriptor(diffTensorDesc, HIPDNN_TENSOR_NCHW, HIPDNN_DATA_DOUBLE,
|
||||
cudnnTensorDescriptor_t diffTensorDesc;
|
||||
cudnnCreateTensorDescriptor(&diffTensorDesc);
|
||||
cudnnSetTensor4dDescriptor(diffTensorDesc, CUDNN_TENSOR_NCHW, CUDNN_DATA_DOUBLE,
|
||||
m, c, 1, 1);
|
||||
|
||||
double *d_gradData;
|
||||
// CHECK: hipMalloc((void**) &d_gradData, m * c * sizeof(double));
|
||||
cudaMalloc((void**) &d_gradData, m * c * sizeof(double));
|
||||
|
||||
double *diffData = makeDiffData(m, c);
|
||||
double *d_diffData;
|
||||
// CHECK: hipMalloc((void**) &d_diffData, m * c * sizeof(double));
|
||||
// CHECK: hipMemcpy(d_diffData, diffData, m * c * sizeof(double), hipMemcpyHostToDevice);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaMalloc((void**) &d_diffData, m * c * sizeof(double));
|
||||
cudaMemcpy(d_diffData, diffData, m * c * sizeof(double), cudaMemcpyHostToDevice);
|
||||
cudaDeviceSynchronize();
|
||||
// CHECK: hipdnnSoftmaxBackward(handle, HIPDNN_SOFTMAX_ACCURATE, HIPDNN_SOFTMAX_MODE_CHANNEL,
|
||||
cudnnSoftmaxBackward(handle, CUDNN_SOFTMAX_ACCURATE, CUDNN_SOFTMAX_MODE_CHANNEL,
|
||||
&one, srcTensorDesc, d_softmaxData, diffTensorDesc, d_diffData, &zero, sftTensorDesc, d_gradData);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
// Copy back
|
||||
double *result_backward = (double *) malloc(m * c * sizeof(double));
|
||||
// CHECK: hipMemcpy(result_backward, d_gradData, m * c * sizeof(double), hipMemcpyDeviceToHost);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaMemcpy(result_backward, d_gradData, m * c * sizeof(double), cudaMemcpyDeviceToHost);
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
// Log
|
||||
printf("GRADIENT:\n");
|
||||
printMatrix(result_backward, c, m);
|
||||
|
||||
// Destruct
|
||||
free(result);
|
||||
free(diffData);
|
||||
free(result_backward);
|
||||
free(fcLayer);
|
||||
|
||||
// CHECK: hipdnnDestroyTensorDescriptor(srcTensorDesc);
|
||||
// CHECK: hipdnnDestroyTensorDescriptor(sftTensorDesc);
|
||||
// CHECK: hipdnnDestroyTensorDescriptor(diffTensorDesc);
|
||||
// CHECK: hipFree(d_fcLayer);
|
||||
// CHECK: hipFree(d_softmaxData);
|
||||
// CHECK: hipFree(d_gradData);
|
||||
// CHECK: hipFree(d_diffData);
|
||||
// CHECK: hipdnnDestroy(handle);
|
||||
cudnnDestroyTensorDescriptor(srcTensorDesc);
|
||||
cudnnDestroyTensorDescriptor(sftTensorDesc);
|
||||
cudnnDestroyTensorDescriptor(diffTensorDesc);
|
||||
cudaFree(d_fcLayer);
|
||||
cudaFree(d_softmaxData);
|
||||
cudaFree(d_gradData);
|
||||
cudaFree(d_diffData);
|
||||
cudnnDestroy(handle);
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda.h>
|
||||
// CHECK: #include <hipfft.h>
|
||||
#include <cufft.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#define DATASIZE 8
|
||||
#define BATCH 2
|
||||
|
||||
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
|
||||
// CHECK: inline void gpuAssert(hipError_t code, const char *file, int line, bool abort = true)
|
||||
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort = true)
|
||||
{
|
||||
// CHECK: if (code != hipSuccess)
|
||||
if (code != cudaSuccess)
|
||||
{
|
||||
// CHECK: fprintf(stderr, "GPUassert: %s %s %dn", hipGetErrorString(code), file, line);
|
||||
fprintf(stderr, "GPUassert: %s %s %dn", cudaGetErrorString(code), file, line);
|
||||
if (abort) exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// --- Host side input data allocation and initialization
|
||||
// CHECK: hipfftReal *hostInputData = (hipfftReal*)malloc(DATASIZE*BATCH * sizeof(hipfftReal));
|
||||
cufftReal *hostInputData = (cufftReal*)malloc(DATASIZE*BATCH * sizeof(cufftReal));
|
||||
for (int i = 0; i<BATCH; i++)
|
||||
for (int j = 0; j<DATASIZE; j++) hostInputData[i*DATASIZE + j] = (cufftReal)(i + 1);
|
||||
|
||||
// --- Device side input data allocation and initialization
|
||||
cufftReal *deviceInputData; gpuErrchk(cudaMalloc((void**)&deviceInputData, DATASIZE * BATCH * sizeof(cufftReal)));
|
||||
// CHECK: hipMemcpy(deviceInputData, hostInputData, DATASIZE * BATCH * sizeof(hipfftReal), hipMemcpyHostToDevice);
|
||||
cudaMemcpy(deviceInputData, hostInputData, DATASIZE * BATCH * sizeof(cufftReal), cudaMemcpyHostToDevice);
|
||||
|
||||
// --- Host side output data allocation
|
||||
cufftComplex *hostOutputData = (cufftComplex*)malloc((DATASIZE / 2 + 1) * BATCH * sizeof(cufftComplex));
|
||||
|
||||
// --- Device side output data allocation
|
||||
cufftComplex *deviceOutputData; gpuErrchk(cudaMalloc((void**)&deviceOutputData, (DATASIZE / 2 + 1) * BATCH * sizeof(cufftComplex)));
|
||||
|
||||
// --- Batched 1D FFTs
|
||||
// CHECK: hipfftHandle handle;
|
||||
cufftHandle handle;
|
||||
int rank = 1; // --- 1D FFTs
|
||||
int n[] = { DATASIZE }; // --- Size of the Fourier transform
|
||||
int istride = 1, ostride = 1; // --- Distance between two successive input/output elements
|
||||
int idist = DATASIZE, odist = (DATASIZE / 2 + 1); // --- Distance between batches
|
||||
int inembed[] = { 0 }; // --- Input size with pitch (ignored for 1D transforms)
|
||||
int onembed[] = { 0 }; // --- Output size with pitch (ignored for 1D transforms)
|
||||
int batch = BATCH; // --- Number of batched executions
|
||||
// CHECK: hipfftPlanMany(&handle, rank, n,
|
||||
cufftPlanMany(&handle, rank, n,
|
||||
inembed, istride, idist,
|
||||
// CHECK: onembed, ostride, odist, HIPFFT_R2C, batch);
|
||||
onembed, ostride, odist, CUFFT_R2C, batch);
|
||||
|
||||
// CHECK: hipfftExecR2C(handle, deviceInputData, deviceOutputData);
|
||||
cufftExecR2C(handle, deviceInputData, deviceOutputData);
|
||||
|
||||
// --- Device->Host copy of the results
|
||||
// CHECK: gpuErrchk(hipMemcpy(hostOutputData, deviceOutputData, (DATASIZE / 2 + 1) * BATCH * sizeof(hipfftComplex), hipMemcpyDeviceToHost));
|
||||
gpuErrchk(cudaMemcpy(hostOutputData, deviceOutputData, (DATASIZE / 2 + 1) * BATCH * sizeof(cufftComplex), cudaMemcpyDeviceToHost));
|
||||
|
||||
for (int i = 0; i<BATCH; i++)
|
||||
for (int j = 0; j<(DATASIZE / 2 + 1); j++)
|
||||
printf("%i %i %f %fn", i, j, hostOutputData[i*(DATASIZE / 2 + 1) + j].x, hostOutputData[i*(DATASIZE / 2 + 1) + j].y);
|
||||
|
||||
// CHECK: hipfftDestroy(handle);
|
||||
cufftDestroy(handle);
|
||||
// CHECK: gpuErrchk(hipFree(deviceOutputData));
|
||||
// CHECK: gpuErrchk(hipFree(deviceInputData));
|
||||
gpuErrchk(cudaFree(deviceOutputData));
|
||||
gpuErrchk(cudaFree(deviceInputData));
|
||||
}
|
||||
-346
@@ -1,346 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// Copyright (c) 2017 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 <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <numeric>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
|
||||
#include "cmdparser.hpp"
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include <hiprand.h>
|
||||
#include <curand.h>
|
||||
|
||||
// CHECK: if ((x) != hipSuccess) {
|
||||
#define CUDA_CALL(x) \
|
||||
do { \
|
||||
if ((x) != cudaSuccess) { \
|
||||
printf("Error at %s:%d\n", __FILE__, __LINE__); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while (0)
|
||||
// CHECK: if ((x) != HIPRAND_STATUS_SUCCESS) {
|
||||
#define CURAND_CALL(x) \
|
||||
do { \
|
||||
if ((x) != CURAND_STATUS_SUCCESS) { \
|
||||
printf("Error at %s:%d\n", __FILE__, __LINE__); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#ifndef DEFAULT_RAND_N
|
||||
const size_t DEFAULT_RAND_N = 1024 * 1024 * 128;
|
||||
#endif
|
||||
|
||||
// CHECK: typedef hiprandRngType_t rng_type_t;
|
||||
typedef curandRngType rng_type_t;
|
||||
|
||||
template <typename T>
|
||||
// CHECK: using generate_func_type = std::function<hiprandStatus_t(hiprandGenerator_t, T*, size_t)>;
|
||||
using generate_func_type = std::function<curandStatus_t(curandGenerator_t, T*, size_t)>;
|
||||
|
||||
template <typename T>
|
||||
void run_benchmark(const cli::Parser& parser, const rng_type_t rng_type,
|
||||
generate_func_type<T> generate_func) {
|
||||
const size_t size = parser.get<size_t>("size");
|
||||
const size_t trials = parser.get<size_t>("trials");
|
||||
|
||||
T* data;
|
||||
// CHECK: CUDA_CALL(hipMalloc((void**)&data, size * sizeof(T)));
|
||||
CUDA_CALL(cudaMalloc((void**)&data, size * sizeof(T)));
|
||||
|
||||
// CHECK: hiprandGenerator_t generator;
|
||||
// CHECK: CURAND_CALL(hiprandCreateGenerator(&generator, rng_type));
|
||||
curandGenerator_t generator;
|
||||
CURAND_CALL(curandCreateGenerator(&generator, rng_type));
|
||||
|
||||
const size_t dimensions = parser.get<size_t>("dimensions");
|
||||
// CHECK: hiprandStatus_t status = hiprandSetQuasiRandomGeneratorDimensions(generator, dimensions);
|
||||
// CHECK: if (status != HIPRAND_STATUS_TYPE_ERROR)
|
||||
curandStatus_t status = curandSetQuasiRandomGeneratorDimensions(generator, dimensions);
|
||||
if (status != CURAND_STATUS_TYPE_ERROR) // If the RNG is not quasi-random
|
||||
{
|
||||
CURAND_CALL(status);
|
||||
}
|
||||
|
||||
// Warm-up
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
CURAND_CALL(generate_func(generator, data, size));
|
||||
}
|
||||
// CHECK: CUDA_CALL(hipDeviceSynchronize());
|
||||
CUDA_CALL(cudaDeviceSynchronize());
|
||||
|
||||
// Measurement
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
for (size_t i = 0; i < trials; i++) {
|
||||
CURAND_CALL(generate_func(generator, data, size));
|
||||
}
|
||||
// CHECK: CUDA_CALL(hipDeviceSynchronize());
|
||||
CUDA_CALL(cudaDeviceSynchronize());
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double, std::milli> elapsed = end - start;
|
||||
|
||||
std::cout << std::fixed << std::setprecision(3) << " "
|
||||
<< "Throughput = " << std::setw(8)
|
||||
<< (trials * size * sizeof(T)) / (elapsed.count() / 1e3 * (1 << 30))
|
||||
<< " GB/s, Samples = " << std::setw(8)
|
||||
<< (trials * size) / (elapsed.count() / 1e3 * (1 << 30))
|
||||
<< " GSample/s, AvgTime (1 trial) = " << std::setw(8) << elapsed.count() / trials
|
||||
<< " ms, Time (all) = " << std::setw(8) << elapsed.count() << " ms, Size = " << size
|
||||
<< std::endl;
|
||||
// CHECK: CURAND_CALL(hiprandDestroyGenerator(generator));
|
||||
// CHECK: CUDA_CALL(hipFree(data));
|
||||
CURAND_CALL(curandDestroyGenerator(generator));
|
||||
CUDA_CALL(cudaFree(data));
|
||||
}
|
||||
|
||||
void run_benchmarks(const cli::Parser& parser, const rng_type_t rng_type,
|
||||
const std::string& distribution) {
|
||||
if (distribution == "uniform-uint") {
|
||||
// CHECK: if (rng_type != HIPRAND_RNG_QUASI_SOBOL64 &&
|
||||
// CHECK: rng_type != HIPRAND_RNG_QUASI_SCRAMBLED_SOBOL64) {
|
||||
if (rng_type != CURAND_RNG_QUASI_SOBOL64 &&
|
||||
rng_type != CURAND_RNG_QUASI_SCRAMBLED_SOBOL64) {
|
||||
run_benchmark<unsigned int>(
|
||||
parser, rng_type,
|
||||
// CHECK: [](hiprandGenerator_t gen, unsigned int* data, size_t size) {
|
||||
// CHECK: return hiprandGenerate(gen, data, size);
|
||||
[](curandGenerator_t gen, unsigned int* data, size_t size) {
|
||||
return curandGenerate(gen, data, size);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (distribution == "uniform-long-long") {
|
||||
// CHECK: if (rng_type == HIPRAND_RNG_QUASI_SOBOL64 ||
|
||||
// CHECK: rng_type == HIPRAND_RNG_QUASI_SCRAMBLED_SOBOL64)
|
||||
if (rng_type == CURAND_RNG_QUASI_SOBOL64 ||
|
||||
rng_type == CURAND_RNG_QUASI_SCRAMBLED_SOBOL64) {
|
||||
run_benchmark<unsigned long long>(
|
||||
parser, rng_type,
|
||||
// CHECK: [](hiprandGenerator_t gen, unsigned long long* data, size_t size) {
|
||||
[](curandGenerator_t gen, unsigned long long* data, size_t size) {
|
||||
// curandGenerateLongLong is yet unsupported by HIP
|
||||
// CHECK-NOT: return hiprandGenerateLongLong(gen, data, size);
|
||||
return curandGenerateLongLong(gen, data, size);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (distribution == "uniform-float") {
|
||||
run_benchmark<float>(parser, rng_type,
|
||||
// CHECK: [](hiprandGenerator_t gen, float* data, size_t size) {
|
||||
// CHECK: return hiprandGenerateUniform(gen, data, size);
|
||||
[](curandGenerator_t gen, float* data, size_t size) {
|
||||
return curandGenerateUniform(gen, data, size);
|
||||
});
|
||||
}
|
||||
if (distribution == "uniform-double") {
|
||||
run_benchmark<double>(parser, rng_type,
|
||||
// CHECK: [](hiprandGenerator_t gen, double* data, size_t size) {
|
||||
// CHECK: return hiprandGenerateUniformDouble(gen, data, size);
|
||||
[](curandGenerator_t gen, double* data, size_t size) {
|
||||
return curandGenerateUniformDouble(gen, data, size);
|
||||
});
|
||||
}
|
||||
if (distribution == "normal-float") {
|
||||
run_benchmark<float>(parser, rng_type,
|
||||
// CHECK: [](hiprandGenerator_t gen, float* data, size_t size) {
|
||||
// CHECK: return hiprandGenerateNormal(gen, data, size, 0.0f, 1.0f);
|
||||
[](curandGenerator_t gen, float* data, size_t size) {
|
||||
return curandGenerateNormal(gen, data, size, 0.0f, 1.0f);
|
||||
});
|
||||
}
|
||||
if (distribution == "normal-double") {
|
||||
run_benchmark<double>(
|
||||
parser, rng_type,
|
||||
// CHECK: [](hiprandGenerator_t gen, double* data, size_t size) {
|
||||
// CHECK: return hiprandGenerateNormalDouble(gen, data, size, 0.0, 1.0);
|
||||
[](curandGenerator_t gen, double* data, size_t size) {
|
||||
return curandGenerateNormalDouble(gen, data, size, 0.0, 1.0);
|
||||
});
|
||||
}
|
||||
if (distribution == "log-normal-float") {
|
||||
run_benchmark<float>(parser, rng_type,
|
||||
// CHECK: [](hiprandGenerator_t gen, float* data, size_t size) {
|
||||
// CHECK: return hiprandGenerateLogNormal(gen, data, size, 0.0f, 1.0f);
|
||||
[](curandGenerator_t gen, float* data, size_t size) {
|
||||
return curandGenerateLogNormal(gen, data, size, 0.0f, 1.0f);
|
||||
});
|
||||
}
|
||||
if (distribution == "log-normal-double") {
|
||||
run_benchmark<double>(
|
||||
parser, rng_type,
|
||||
// CHECK: [](hiprandGenerator_t gen, double* data, size_t size) {
|
||||
// CHECK: return hiprandGenerateLogNormalDouble(gen, data, size, 0.0, 1.0);
|
||||
[](curandGenerator_t gen, double* data, size_t size) {
|
||||
return curandGenerateLogNormalDouble(gen, data, size, 0.0, 1.0);
|
||||
});
|
||||
}
|
||||
if (distribution == "poisson") {
|
||||
const auto lambdas = parser.get<std::vector<double>>("lambda");
|
||||
for (double lambda : lambdas) {
|
||||
std::cout << " "
|
||||
<< "lambda " << std::fixed << std::setprecision(1) << lambda << std::endl;
|
||||
run_benchmark<unsigned int>(
|
||||
parser, rng_type,
|
||||
// CHECK: [lambda](hiprandGenerator_t gen, unsigned int* data, size_t size) {
|
||||
// CHECK: return hiprandGeneratePoisson(gen, data, size, lambda);
|
||||
[lambda](curandGenerator_t gen, unsigned int* data, size_t size) {
|
||||
return curandGeneratePoisson(gen, data, size, lambda);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<std::string> all_engines = {
|
||||
"xorwow", "mrg32k3a", "mtgp32",
|
||||
// "mt19937",
|
||||
"philox", "sobol32",
|
||||
// "scrambled_sobol32",
|
||||
// "sobol64",
|
||||
// "scrambled_sobol64",
|
||||
};
|
||||
|
||||
const std::vector<std::string> all_distributions = {
|
||||
"uniform-uint", "uniform-long-long", "uniform-float", "uniform-double", "normal-float",
|
||||
"normal-double", "log-normal-float", "log-normal-double", "poisson"};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
cli::Parser parser(argc, argv);
|
||||
|
||||
const std::string distribution_desc =
|
||||
"space-separated list of distributions:" +
|
||||
std::accumulate(all_distributions.begin(), all_distributions.end(), std::string(),
|
||||
[](std::string a, std::string b) { return a + "\n " + b; }) +
|
||||
"\n or all";
|
||||
const std::string engine_desc =
|
||||
"space-separated list of random number engines:" +
|
||||
std::accumulate(all_engines.begin(), all_engines.end(), std::string(),
|
||||
[](std::string a, std::string b) { return a + "\n " + b; }) +
|
||||
"\n or all";
|
||||
|
||||
parser.set_optional<size_t>("size", "size", DEFAULT_RAND_N, "number of values");
|
||||
parser.set_optional<size_t>("dimensions", "dimensions", 1,
|
||||
"number of dimensions of quasi-random values");
|
||||
parser.set_optional<size_t>("trials", "trials", 20, "number of trials");
|
||||
parser.set_optional<std::vector<std::string>>("dis", "dis", {"uniform-uint"},
|
||||
distribution_desc.c_str());
|
||||
parser.set_optional<std::vector<std::string>>("engine", "engine", {"philox"},
|
||||
engine_desc.c_str());
|
||||
parser.set_optional<std::vector<double>>(
|
||||
"lambda", "lambda", {10.0}, "space-separated list of lambdas of Poisson distribution");
|
||||
parser.run_and_exit_if_error();
|
||||
|
||||
std::vector<std::string> engines;
|
||||
{
|
||||
auto es = parser.get<std::vector<std::string>>("engine");
|
||||
if (std::find(es.begin(), es.end(), "all") != es.end()) {
|
||||
engines = all_engines;
|
||||
} else {
|
||||
for (auto e : all_engines) {
|
||||
if (std::find(es.begin(), es.end(), e) != es.end()) engines.push_back(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> distributions;
|
||||
{
|
||||
auto ds = parser.get<std::vector<std::string>>("dis");
|
||||
if (std::find(ds.begin(), ds.end(), "all") != ds.end()) {
|
||||
distributions = all_distributions;
|
||||
} else {
|
||||
for (auto d : all_distributions) {
|
||||
if (std::find(ds.begin(), ds.end(), d) != ds.end()) distributions.push_back(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int version;
|
||||
// CHECK: CURAND_CALL(hiprandGetVersion(&version));
|
||||
CURAND_CALL(curandGetVersion(&version));
|
||||
int runtime_version;
|
||||
// cudaRuntimeGetVersion is yet unsupported by HIP
|
||||
// CHECK: CUDA_CALL(hipRuntimeGetVersion(&runtime_version));
|
||||
CUDA_CALL(cudaRuntimeGetVersion(&runtime_version));
|
||||
int device_id;
|
||||
// CHECK: CUDA_CALL(hipGetDevice(&device_id));
|
||||
// CHECK: hipDeviceProp_t props;
|
||||
// CHECK: CUDA_CALL(hipGetDeviceProperties(&props, device_id));
|
||||
CUDA_CALL(cudaGetDevice(&device_id));
|
||||
cudaDeviceProp props;
|
||||
CUDA_CALL(cudaGetDeviceProperties(&props, device_id));
|
||||
|
||||
std::cout << "cuRAND: " << version << " ";
|
||||
std::cout << "Runtime: " << runtime_version << " ";
|
||||
std::cout << "Device: " << props.name;
|
||||
std::cout << std::endl << std::endl;
|
||||
|
||||
for (auto engine : engines) {
|
||||
// CHECK: rng_type_t rng_type = HIPRAND_RNG_PSEUDO_XORWOW;
|
||||
// CHECK: rng_type = HIPRAND_RNG_PSEUDO_XORWOW;
|
||||
// CHECK: rng_type = HIPRAND_RNG_PSEUDO_MRG32K3A;
|
||||
// CHECK: rng_type = HIPRAND_RNG_PSEUDO_MTGP32;
|
||||
// CHECK: rng_type = HIPRAND_RNG_PSEUDO_MT19937;
|
||||
// CHECK: rng_type = HIPRAND_RNG_PSEUDO_PHILOX4_32_10;
|
||||
// CHECK: rng_type = HIPRAND_RNG_QUASI_SOBOL32;
|
||||
// CHECK: rng_type = HIPRAND_RNG_QUASI_SCRAMBLED_SOBOL32;
|
||||
// CHECK: rng_type = HIPRAND_RNG_QUASI_SOBOL64;
|
||||
// CHECK: rng_type = HIPRAND_RNG_QUASI_SCRAMBLED_SOBOL64;
|
||||
rng_type_t rng_type = CURAND_RNG_PSEUDO_XORWOW;
|
||||
if (engine == "xorwow")
|
||||
rng_type = CURAND_RNG_PSEUDO_XORWOW;
|
||||
else if (engine == "mrg32k3a")
|
||||
rng_type = CURAND_RNG_PSEUDO_MRG32K3A;
|
||||
else if (engine == "mtgp32")
|
||||
rng_type = CURAND_RNG_PSEUDO_MTGP32;
|
||||
else if (engine == "mt19937")
|
||||
rng_type = CURAND_RNG_PSEUDO_MT19937;
|
||||
else if (engine == "philox")
|
||||
rng_type = CURAND_RNG_PSEUDO_PHILOX4_32_10;
|
||||
else if (engine == "sobol32")
|
||||
rng_type = CURAND_RNG_QUASI_SOBOL32;
|
||||
else if (engine == "scrambled_sobol32")
|
||||
rng_type = CURAND_RNG_QUASI_SCRAMBLED_SOBOL32;
|
||||
else if (engine == "sobol64")
|
||||
rng_type = CURAND_RNG_QUASI_SOBOL64;
|
||||
else if (engine == "scrambled_sobol64")
|
||||
rng_type = CURAND_RNG_QUASI_SCRAMBLED_SOBOL64;
|
||||
else {
|
||||
std::cout << "Wrong engine name" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::cout << engine << ":" << std::endl;
|
||||
|
||||
for (auto distribution : distributions) {
|
||||
std::cout << " " << distribution << ":" << std::endl;
|
||||
run_benchmarks(parser, rng_type, distribution);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
-673
@@ -1,673 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// Copyright (c) 2017 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 <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <numeric>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
|
||||
#include "cmdparser.hpp"
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include <hiprand.h>
|
||||
#include <curand.h>
|
||||
// CHECK: #include <hiprand_kernel.h>
|
||||
#include <curand_kernel.h>
|
||||
// CHECK: #include <hiprand_mtgp32_host.h>
|
||||
#include <curand_mtgp32_host.h>
|
||||
// CHECK: #include <rocrand_mtgp32_11213.h>
|
||||
#include <curand_mtgp32dc_p_11213.h>
|
||||
|
||||
// CHECK: if ((x) != hipSuccess) {
|
||||
#define CUDA_CALL(x) \
|
||||
do { \
|
||||
if ((x) != cudaSuccess) { \
|
||||
printf("Error at %s:%d\n", __FILE__, __LINE__); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while (0)
|
||||
// CHECK: if ((x) != HIPRAND_STATUS_SUCCESS) {
|
||||
#define CURAND_CALL(x) \
|
||||
do { \
|
||||
if ((x) != CURAND_STATUS_SUCCESS) { \
|
||||
printf("Error at %s:%d\n", __FILE__, __LINE__); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#ifndef DEFAULT_RAND_N
|
||||
const size_t DEFAULT_RAND_N = 1024 * 1024 * 128;
|
||||
#endif
|
||||
|
||||
size_t next_power2(size_t x)
|
||||
{
|
||||
size_t power = 1;
|
||||
while (power < x)
|
||||
{
|
||||
power *= 2;
|
||||
}
|
||||
return power;
|
||||
}
|
||||
|
||||
template<typename GeneratorState>
|
||||
__global__
|
||||
void init_kernel(GeneratorState * states,
|
||||
const unsigned long long seed,
|
||||
const unsigned long long offset)
|
||||
{
|
||||
const unsigned int state_id = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
GeneratorState state;
|
||||
// CHECK: hiprand_init(seed, state_id, offset, &state);
|
||||
curand_init(seed, state_id, offset, &state);
|
||||
states[state_id] = state;
|
||||
}
|
||||
|
||||
template<typename GeneratorState, typename T, typename GenerateFunc, typename Extra>
|
||||
__global__
|
||||
void generate_kernel(GeneratorState * states,
|
||||
T * data,
|
||||
const size_t size,
|
||||
const GenerateFunc& generate_func,
|
||||
const Extra extra)
|
||||
{
|
||||
const unsigned int state_id = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
const unsigned int stride = gridDim.x * blockDim.x;
|
||||
|
||||
GeneratorState state = states[state_id];
|
||||
unsigned int index = state_id;
|
||||
while(index < size)
|
||||
{
|
||||
data[index] = generate_func(&state, extra);
|
||||
index += stride;
|
||||
}
|
||||
states[state_id] = state;
|
||||
}
|
||||
|
||||
template<typename GeneratorState>
|
||||
struct runner
|
||||
{
|
||||
GeneratorState * states;
|
||||
|
||||
runner(const size_t dimensions,
|
||||
const size_t blocks,
|
||||
const size_t threads,
|
||||
const unsigned long long seed,
|
||||
const unsigned long long offset)
|
||||
{
|
||||
const size_t states_size = blocks * threads;
|
||||
// CHECK: CUDA_CALL(hipMalloc((void **)&states, states_size * sizeof(GeneratorState)));
|
||||
CUDA_CALL(cudaMalloc((void **)&states, states_size * sizeof(GeneratorState)));
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(init_kernel), dim3(blocks), dim3(threads), 0, 0, states, seed, offset);
|
||||
init_kernel<<<blocks, threads>>>(states, seed, offset);
|
||||
// CHECK: CUDA_CALL(hipPeekAtLastError());
|
||||
// CHECK: CUDA_CALL(hipDeviceSynchronize());
|
||||
CUDA_CALL(cudaPeekAtLastError());
|
||||
CUDA_CALL(cudaDeviceSynchronize());
|
||||
}
|
||||
|
||||
~runner()
|
||||
{
|
||||
CUDA_CALL(cudaFree(states));
|
||||
}
|
||||
|
||||
template<typename T, typename GenerateFunc, typename Extra>
|
||||
void generate(const size_t blocks,
|
||||
const size_t threads,
|
||||
T * data,
|
||||
const size_t size,
|
||||
const GenerateFunc& generate_func,
|
||||
const Extra extra)
|
||||
{
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(generate_kernel), dim3(blocks), dim3(threads), 0, 0, states, data, size, generate_func, extra);
|
||||
generate_kernel<<<blocks, threads>>>(states, data, size, generate_func, extra);
|
||||
}
|
||||
};
|
||||
|
||||
// CHECK: void generate_kernel(hiprandStateMtgp32_t * states,
|
||||
template<typename T, typename GenerateFunc, typename Extra>
|
||||
__global__
|
||||
void generate_kernel(curandStateMtgp32_t * states,
|
||||
T * data,
|
||||
const size_t size,
|
||||
const GenerateFunc& generate_func,
|
||||
const Extra extra)
|
||||
{
|
||||
const unsigned int state_id = blockIdx.x;
|
||||
const unsigned int thread_id = threadIdx.x;
|
||||
unsigned int index = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
unsigned int stride = gridDim.x * blockDim.x;
|
||||
// CHECK: __shared__ hiprandStateMtgp32_t state;
|
||||
__shared__ curandStateMtgp32_t state;
|
||||
|
||||
if (thread_id == 0)
|
||||
state = states[state_id];
|
||||
__syncthreads();
|
||||
|
||||
const size_t r = size%blockDim.x;
|
||||
const size_t size_rounded_up = r == 0 ? size : size + (blockDim.x - r);
|
||||
while(index < size_rounded_up)
|
||||
{
|
||||
auto value = generate_func(&state, extra);
|
||||
if(index < size)
|
||||
data[index] = value;
|
||||
index += stride;
|
||||
}
|
||||
__syncthreads();
|
||||
|
||||
if (thread_id == 0)
|
||||
states[state_id] = state;
|
||||
}
|
||||
|
||||
// CHECK: struct runner<hiprandStateMtgp32_t>
|
||||
template<>
|
||||
struct runner<curandStateMtgp32_t>
|
||||
{
|
||||
// CHECK: hiprandStateMtgp32_t * states;
|
||||
curandStateMtgp32_t * states;
|
||||
mtgp32_kernel_params_t * d_param;
|
||||
|
||||
runner(const size_t dimensions,
|
||||
const size_t blocks,
|
||||
const size_t threads,
|
||||
const unsigned long long seed,
|
||||
const unsigned long long offset)
|
||||
{
|
||||
const size_t states_size = std::min((size_t)200, blocks);
|
||||
// CHECK: CUDA_CALL(hipMalloc((void **)&states, states_size * sizeof(hiprandStateMtgp32_t)));
|
||||
CUDA_CALL(cudaMalloc((void **)&states, states_size * sizeof(curandStateMtgp32_t)));
|
||||
// CHECK: CUDA_CALL(hipMalloc((void **)&d_param, sizeof(mtgp32_kernel_params)));
|
||||
CUDA_CALL(cudaMalloc((void **)&d_param, sizeof(mtgp32_kernel_params)));
|
||||
// CHECK: CURAND_CALL(hiprandMakeMTGP32Constants(mtgp32dc_params_fast_11213, d_param));
|
||||
CURAND_CALL(curandMakeMTGP32Constants(mtgp32dc_params_fast_11213, d_param));
|
||||
// CHECK: CURAND_CALL(hiprandMakeMTGP32KernelState(states, mtgp32dc_params_fast_11213, d_param, states_size, seed));
|
||||
CURAND_CALL(curandMakeMTGP32KernelState(states, mtgp32dc_params_fast_11213, d_param, states_size, seed));
|
||||
}
|
||||
|
||||
~runner()
|
||||
{
|
||||
// CHECK: CUDA_CALL(hipFree(states));
|
||||
// CHECK: CUDA_CALL(hipFree(d_param));
|
||||
CUDA_CALL(cudaFree(states));
|
||||
CUDA_CALL(cudaFree(d_param));
|
||||
}
|
||||
|
||||
template<typename T, typename GenerateFunc, typename Extra>
|
||||
void generate(const size_t blocks,
|
||||
const size_t threads,
|
||||
T * data,
|
||||
const size_t size,
|
||||
const GenerateFunc& generate_func,
|
||||
const Extra extra)
|
||||
{
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(generate_kernel), dim3(std::min((size_t)200, blocks)), dim3(256), 0, 0, states, data, size, generate_func, extra);
|
||||
generate_kernel<<<std::min((size_t)200, blocks), 256>>>(states, data, size, generate_func, extra);
|
||||
}
|
||||
};
|
||||
|
||||
// CHECK: void init_kernel(hiprandStateSobol32_t * states,
|
||||
template<typename Directions>
|
||||
__global__
|
||||
void init_kernel(curandStateSobol32_t * states,
|
||||
const Directions directions,
|
||||
const unsigned long long offset)
|
||||
{
|
||||
const unsigned int dimension = blockIdx.y;
|
||||
const unsigned int state_id = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
// CHECK: hiprandStateSobol32_t state;
|
||||
// CHECK: hiprand_init(directions[dimension], offset + state_id, &state);
|
||||
curandStateSobol32_t state;
|
||||
curand_init(directions[dimension], offset + state_id, &state);
|
||||
states[gridDim.x * blockDim.x * dimension + state_id] = state;
|
||||
}
|
||||
|
||||
// CHECK: void generate_kernel(hiprandStateSobol32_t * states,
|
||||
template<typename T, typename GenerateFunc, typename Extra>
|
||||
__global__
|
||||
void generate_kernel(curandStateSobol32_t * states,
|
||||
T * data,
|
||||
const size_t size,
|
||||
const GenerateFunc& generate_func,
|
||||
const Extra extra)
|
||||
{
|
||||
const unsigned int dimension = blockIdx.y;
|
||||
const unsigned int state_id = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
const unsigned int stride = gridDim.x * blockDim.x;
|
||||
// CHECK: hiprandStateSobol32_t state = states[gridDim.x * blockDim.x * dimension + state_id];
|
||||
curandStateSobol32_t state = states[gridDim.x * blockDim.x * dimension + state_id];
|
||||
const unsigned int offset = dimension * size;
|
||||
unsigned int index = state_id;
|
||||
while(index < size)
|
||||
{
|
||||
data[offset + index] = generate_func(&state, extra);
|
||||
skipahead(stride - 1, &state);
|
||||
index += stride;
|
||||
}
|
||||
state = states[gridDim.x * blockDim.x * dimension + state_id];
|
||||
skipahead(static_cast<unsigned int>(size), &state);
|
||||
states[gridDim.x * blockDim.x * dimension + state_id] = state;
|
||||
}
|
||||
|
||||
// CHECK: struct runner<hiprandStateSobol32_t>
|
||||
template<>
|
||||
struct runner<curandStateSobol32_t>
|
||||
{
|
||||
// CHECK: hiprandStateSobol32_t * states;
|
||||
curandStateSobol32_t * states;
|
||||
size_t dimensions;
|
||||
|
||||
runner(const size_t dimensions,
|
||||
const size_t blocks,
|
||||
const size_t threads,
|
||||
const unsigned long long seed,
|
||||
const unsigned long long offset)
|
||||
{
|
||||
this->dimensions = dimensions;
|
||||
// CHECK: CUDA_CALL(hipMalloc((void **)&states, states_size * sizeof(hiprandStateSobol32_t)));
|
||||
const size_t states_size = blocks * threads * dimensions;
|
||||
CUDA_CALL(cudaMalloc((void **)&states, states_size * sizeof(curandStateSobol32_t)));
|
||||
// CHECK: hiprandDirectionVectors32_t * directions;
|
||||
curandDirectionVectors32_t * directions;
|
||||
// CHECK: const size_t size = dimensions * sizeof(hiprandDirectionVectors32_t);
|
||||
const size_t size = dimensions * sizeof(curandDirectionVectors32_t);
|
||||
// CHECK: CUDA_CALL(hipMalloc((void **)&directions, size));
|
||||
CUDA_CALL(cudaMalloc((void **)&directions, size));
|
||||
// CHECK: hiprandDirectionVectors32_t * h_directions;
|
||||
curandDirectionVectors32_t * h_directions;
|
||||
// hiprandGetDirectionVectors32 and HIPRAND_DIRECTION_VECTORS_32_JOEKUO6 (of hiprandDirectionVectorSet_t) are yet unsupported by HIP
|
||||
// CHECK-NOT: CURAND_CALL(hiprandGetDirectionVectors32(&h_directions, HIPRAND_DIRECTION_VECTORS_32_JOEKUO6));
|
||||
CURAND_CALL(curandGetDirectionVectors32(&h_directions, CURAND_DIRECTION_VECTORS_32_JOEKUO6));
|
||||
// CHECK: CUDA_CALL(hipMemcpy(directions, h_directions, size, hipMemcpyHostToDevice));
|
||||
CUDA_CALL(cudaMemcpy(directions, h_directions, size, cudaMemcpyHostToDevice));
|
||||
|
||||
const size_t blocks_x = next_power2((blocks + dimensions - 1) / dimensions);
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(init_kernel), dim3(blocks_x, dimensions), dim3(threads), 0, 0, states, directions, offset);
|
||||
init_kernel<<<dim3(blocks_x, dimensions), threads>>>(states, directions, offset);
|
||||
// CHECK: CUDA_CALL(hipPeekAtLastError());
|
||||
// CHECK: CUDA_CALL(hipDeviceSynchronize());
|
||||
CUDA_CALL(cudaPeekAtLastError());
|
||||
CUDA_CALL(cudaDeviceSynchronize());
|
||||
// CHECK: CUDA_CALL(hipFree(directions));
|
||||
CUDA_CALL(cudaFree(directions));
|
||||
}
|
||||
|
||||
~runner()
|
||||
{
|
||||
// CHECK: CUDA_CALL(hipFree(states));
|
||||
CUDA_CALL(cudaFree(states));
|
||||
}
|
||||
|
||||
template<typename T, typename GenerateFunc, typename Extra>
|
||||
void generate(const size_t blocks,
|
||||
const size_t threads,
|
||||
T * data,
|
||||
const size_t size,
|
||||
const GenerateFunc& generate_func,
|
||||
const Extra extra)
|
||||
{
|
||||
const size_t blocks_x = next_power2((blocks + dimensions - 1) / dimensions);
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(generate_kernel), dim3(blocks_x, dimensions), dim3(threads), 0, 0, states, data, size / dimensions, generate_func, extra);
|
||||
generate_kernel<<<dim3(blocks_x, dimensions), threads>>>(states, data, size / dimensions, generate_func, extra);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename GeneratorState, typename GenerateFunc, typename Extra>
|
||||
void run_benchmark(const cli::Parser& parser,
|
||||
const GenerateFunc& generate_func,
|
||||
const Extra extra)
|
||||
{
|
||||
const size_t size = parser.get<size_t>("size");
|
||||
const size_t dimensions = parser.get<size_t>("dimensions");
|
||||
const size_t trials = parser.get<size_t>("trials");
|
||||
|
||||
const size_t blocks = parser.get<size_t>("blocks");
|
||||
const size_t threads = parser.get<size_t>("threads");
|
||||
|
||||
T * data;
|
||||
// CHECK: CUDA_CALL(hipMalloc((void **)&data, size * sizeof(T)));
|
||||
CUDA_CALL(cudaMalloc((void **)&data, size * sizeof(T)));
|
||||
|
||||
runner<GeneratorState> r(dimensions, blocks, threads, 12345ULL, 6789ULL);
|
||||
|
||||
// Warm-up
|
||||
for (size_t i = 0; i < 5; i++)
|
||||
{
|
||||
r.generate(blocks, threads, data, size, generate_func, extra);
|
||||
// CHECK: CUDA_CALL(hipPeekAtLastError());
|
||||
// CHECK: CUDA_CALL(hipDeviceSynchronize());
|
||||
CUDA_CALL(cudaPeekAtLastError());
|
||||
CUDA_CALL(cudaDeviceSynchronize());
|
||||
}
|
||||
// CHECK: CUDA_CALL(hipDeviceSynchronize());
|
||||
CUDA_CALL(cudaDeviceSynchronize());
|
||||
|
||||
// Measurement
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
for (size_t i = 0; i < trials; i++)
|
||||
{
|
||||
r.generate(blocks, threads, data, size, generate_func, extra);
|
||||
}
|
||||
// CHECK: CUDA_CALL(hipPeekAtLastError());
|
||||
// CHECK: CUDA_CALL(hipDeviceSynchronize());
|
||||
CUDA_CALL(cudaPeekAtLastError());
|
||||
CUDA_CALL(cudaDeviceSynchronize());
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double, std::milli> elapsed = end - start;
|
||||
|
||||
std::cout << std::fixed << std::setprecision(3)
|
||||
<< " "
|
||||
<< "Throughput = "
|
||||
<< std::setw(8) << (trials * size * sizeof(T)) /
|
||||
(elapsed.count() / 1e3 * (1 << 30))
|
||||
<< " GB/s, Samples = "
|
||||
<< std::setw(8) << (trials * size) /
|
||||
(elapsed.count() / 1e3 * (1 << 30))
|
||||
<< " GSample/s, AvgTime (1 trial) = "
|
||||
<< std::setw(8) << elapsed.count() / trials
|
||||
<< " ms, Time (all) = "
|
||||
<< std::setw(8) << elapsed.count()
|
||||
<< " ms, Size = " << size
|
||||
<< std::endl;
|
||||
// CHECK: CUDA_CALL(hipFree(data));
|
||||
CUDA_CALL(cudaFree(data));
|
||||
}
|
||||
|
||||
template<typename GeneratorState>
|
||||
void run_benchmarks(const cli::Parser& parser,
|
||||
const std::string& distribution)
|
||||
{
|
||||
if (distribution == "uniform-uint")
|
||||
{
|
||||
// curandStateSobol64_t and curandStateScrambledSobol64_t are yet unsupported by HIP
|
||||
// CHECK-NOT: if (!std::is_same<GeneratorState, hiprandStateSobol64_t>::value &&
|
||||
// CHECK-NOT: !std::is_same<GeneratorState, hiprandStateScrambledSobol64_t>::value)
|
||||
if (!std::is_same<GeneratorState, curandStateSobol64_t>::value &&
|
||||
!std::is_same<GeneratorState, curandStateScrambledSobol64_t>::value)
|
||||
{
|
||||
run_benchmark<unsigned int, GeneratorState>(parser,
|
||||
[] __device__ (GeneratorState * state, int) {
|
||||
// CHECK: return hiprand(state);
|
||||
return curand(state);
|
||||
}, 0
|
||||
);
|
||||
}
|
||||
}
|
||||
if (distribution == "uniform-long-long")
|
||||
{
|
||||
// curandStateSobol64_t and curandStateScrambledSobol64_t are yet unsupported by HIP
|
||||
// CHECK-NOT: if (!std::is_same<GeneratorState, hiprandStateSobol64_t>::value &&
|
||||
// CHECK-NOT: !std::is_same<GeneratorState, hiprandStateScrambledSobol64_t>::value)
|
||||
if (std::is_same<GeneratorState, curandStateSobol64_t>::value ||
|
||||
std::is_same<GeneratorState, curandStateScrambledSobol64_t>::value)
|
||||
{
|
||||
run_benchmark<unsigned long long, GeneratorState>(parser,
|
||||
[] __device__ (GeneratorState * state, int) {
|
||||
// CHECK: return hiprand(state);
|
||||
return curand(state);
|
||||
}, 0
|
||||
);
|
||||
}
|
||||
}
|
||||
if (distribution == "uniform-float")
|
||||
{
|
||||
run_benchmark<float, GeneratorState>(parser,
|
||||
[] __device__ (GeneratorState * state, int) {
|
||||
// CHECK: return hiprand_uniform(state);
|
||||
return curand_uniform(state);
|
||||
}, 0
|
||||
);
|
||||
}
|
||||
if (distribution == "uniform-double")
|
||||
{
|
||||
run_benchmark<double, GeneratorState>(parser,
|
||||
[] __device__ (GeneratorState * state, int) {
|
||||
// CHECK: return hiprand_uniform_double(state);
|
||||
return curand_uniform_double(state);
|
||||
}, 0
|
||||
);
|
||||
}
|
||||
if (distribution == "normal-float")
|
||||
{
|
||||
run_benchmark<float, GeneratorState>(parser,
|
||||
[] __device__ (GeneratorState * state, int) {
|
||||
// CHECK: return hiprand_normal(state);
|
||||
return curand_normal(state);
|
||||
}, 0
|
||||
);
|
||||
}
|
||||
if (distribution == "normal-double")
|
||||
{
|
||||
run_benchmark<double, GeneratorState>(parser,
|
||||
[] __device__ (GeneratorState * state, int) {
|
||||
// CHECK: return hiprand_normal_double(state);
|
||||
return curand_normal_double(state);
|
||||
}, 0
|
||||
);
|
||||
}
|
||||
if (distribution == "log-normal-float")
|
||||
{
|
||||
run_benchmark<float, GeneratorState>(parser,
|
||||
[] __device__ (GeneratorState * state, int) {
|
||||
// CHECK: return hiprand_log_normal(state, 0.0f, 1.0f);
|
||||
return curand_log_normal(state, 0.0f, 1.0f);
|
||||
}, 0
|
||||
);
|
||||
}
|
||||
if (distribution == "log-normal-double")
|
||||
{
|
||||
run_benchmark<double, GeneratorState>(parser,
|
||||
[] __device__ (GeneratorState * state, int) {
|
||||
// CHECK: return hiprand_log_normal_double(state, 0.0, 1.0);
|
||||
return curand_log_normal_double(state, 0.0, 1.0);
|
||||
}, 0
|
||||
);
|
||||
}
|
||||
if (distribution == "poisson")
|
||||
{
|
||||
const auto lambdas = parser.get<std::vector<double>>("lambda");
|
||||
for (double lambda : lambdas)
|
||||
{
|
||||
std::cout << " " << "lambda "
|
||||
<< std::fixed << std::setprecision(1) << lambda << std::endl;
|
||||
run_benchmark<unsigned int, GeneratorState>(parser,
|
||||
[] __device__ (GeneratorState * state, double lambda) {
|
||||
// CHECK: return hiprand_poisson(state, lambda);
|
||||
return curand_poisson(state, lambda);
|
||||
}, lambda
|
||||
);
|
||||
}
|
||||
}
|
||||
if (distribution == "discrete-poisson")
|
||||
{
|
||||
const auto lambdas = parser.get<std::vector<double>>("lambda");
|
||||
for (double lambda : lambdas)
|
||||
{
|
||||
std::cout << " " << "lambda "
|
||||
<< std::fixed << std::setprecision(1) << lambda << std::endl;
|
||||
// CHECK: hiprandDiscreteDistribution_t discrete_distribution;
|
||||
curandDiscreteDistribution_t discrete_distribution;
|
||||
// CHECK: CURAND_CALL(hiprandCreatePoissonDistribution(lambda, &discrete_distribution));
|
||||
CURAND_CALL(curandCreatePoissonDistribution(lambda, &discrete_distribution));
|
||||
run_benchmark<unsigned int, GeneratorState>(parser,
|
||||
// CHECK: [] __device__ (GeneratorState * state, hiprandDiscreteDistribution_t discrete_distribution) {
|
||||
[] __device__ (GeneratorState * state, curandDiscreteDistribution_t discrete_distribution) {
|
||||
// CHECK: return hiprand_discrete(state, discrete_distribution);
|
||||
return curand_discrete(state, discrete_distribution);
|
||||
}, discrete_distribution
|
||||
);
|
||||
// CHECK: CURAND_CALL(hiprandDestroyDistribution(discrete_distribution));
|
||||
CURAND_CALL(curandDestroyDistribution(discrete_distribution));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<std::string> all_engines = {
|
||||
"xorwow",
|
||||
"mrg32k3a",
|
||||
"mtgp32",
|
||||
// "mt19937",
|
||||
"philox",
|
||||
"sobol32",
|
||||
// "scrambled_sobol32",
|
||||
// "sobol64",
|
||||
// "scrambled_sobol64",
|
||||
};
|
||||
|
||||
const std::vector<std::string> all_distributions = {
|
||||
"uniform-uint",
|
||||
// "uniform-long-long",
|
||||
"uniform-float",
|
||||
"uniform-double",
|
||||
"normal-float",
|
||||
"normal-double",
|
||||
"log-normal-float",
|
||||
"log-normal-double",
|
||||
"poisson",
|
||||
"discrete-poisson",
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
cli::Parser parser(argc, argv);
|
||||
|
||||
const std::string distribution_desc =
|
||||
"space-separated list of distributions:" +
|
||||
std::accumulate(all_distributions.begin(), all_distributions.end(), std::string(),
|
||||
[](std::string a, std::string b) {
|
||||
return a + "\n " + b;
|
||||
}
|
||||
) +
|
||||
"\n or all";
|
||||
const std::string engine_desc =
|
||||
"space-separated list of random number engines:" +
|
||||
std::accumulate(all_engines.begin(), all_engines.end(), std::string(),
|
||||
[](std::string a, std::string b) {
|
||||
return a + "\n " + b;
|
||||
}
|
||||
) +
|
||||
"\n or all";
|
||||
|
||||
parser.set_optional<size_t>("size", "size", DEFAULT_RAND_N, "number of values");
|
||||
parser.set_optional<size_t>("dimensions", "dimensions", 1, "number of dimensions of quasi-random values");
|
||||
parser.set_optional<size_t>("trials", "trials", 20, "number of trials");
|
||||
parser.set_optional<size_t>("blocks", "blocks", 256, "number of blocks");
|
||||
parser.set_optional<size_t>("threads", "threads", 256, "number of threads in each block");
|
||||
parser.set_optional<std::vector<std::string>>("dis", "dis", {"uniform-uint"}, distribution_desc.c_str());
|
||||
parser.set_optional<std::vector<std::string>>("engine", "engine", {"philox"}, engine_desc.c_str());
|
||||
parser.set_optional<std::vector<double>>("lambda", "lambda", {10.0}, "space-separated list of lambdas of Poisson distribution");
|
||||
parser.run_and_exit_if_error();
|
||||
|
||||
std::vector<std::string> engines;
|
||||
{
|
||||
auto es = parser.get<std::vector<std::string>>("engine");
|
||||
if (std::find(es.begin(), es.end(), "all") != es.end())
|
||||
{
|
||||
engines = all_engines;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto e : all_engines)
|
||||
{
|
||||
if (std::find(es.begin(), es.end(), e) != es.end())
|
||||
engines.push_back(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> distributions;
|
||||
{
|
||||
auto ds = parser.get<std::vector<std::string>>("dis");
|
||||
if (std::find(ds.begin(), ds.end(), "all") != ds.end())
|
||||
{
|
||||
distributions = all_distributions;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto d : all_distributions)
|
||||
{
|
||||
if (std::find(ds.begin(), ds.end(), d) != ds.end())
|
||||
distributions.push_back(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int version;
|
||||
// CHECK: CURAND_CALL(hiprandGetVersion(&version));
|
||||
CURAND_CALL(curandGetVersion(&version));
|
||||
int runtime_version;
|
||||
// cudaRuntimeGetVersion is yet unsupported by HIP
|
||||
// CHECK: CUDA_CALL(hipRuntimeGetVersion(&runtime_version));
|
||||
CUDA_CALL(cudaRuntimeGetVersion(&runtime_version));
|
||||
int device_id;
|
||||
// CHECK: CUDA_CALL(hipGetDevice(&device_id));
|
||||
// CHECK: hipDeviceProp_t props;
|
||||
// CHECK: CUDA_CALL(hipGetDeviceProperties(&props, device_id));
|
||||
CUDA_CALL(cudaGetDevice(&device_id));
|
||||
cudaDeviceProp props;
|
||||
CUDA_CALL(cudaGetDeviceProperties(&props, device_id));
|
||||
|
||||
std::cout << "cuRAND: " << version << " ";
|
||||
std::cout << "Runtime: " << runtime_version << " ";
|
||||
std::cout << "Device: " << props.name;
|
||||
std::cout << std::endl << std::endl;
|
||||
|
||||
for (auto engine : engines)
|
||||
{
|
||||
std::cout << engine << ":" << std::endl;
|
||||
for (auto distribution : distributions)
|
||||
{
|
||||
std::cout << " " << distribution << ":" << std::endl;
|
||||
const std::string plot_name = engine + "-" + distribution;
|
||||
if (engine == "xorwow")
|
||||
{
|
||||
// CHECK: run_benchmarks<hiprandStateXORWOW_t>(parser, distribution);
|
||||
run_benchmarks<curandStateXORWOW_t>(parser, distribution);
|
||||
}
|
||||
else if (engine == "mrg32k3a")
|
||||
{
|
||||
// CHECK: run_benchmarks<hiprandStateMRG32k3a_t>(parser, distribution);
|
||||
run_benchmarks<curandStateMRG32k3a_t>(parser, distribution);
|
||||
}
|
||||
else if (engine == "philox")
|
||||
{
|
||||
// CHECK: run_benchmarks<hiprandStatePhilox4_32_10_t>(parser, distribution);
|
||||
run_benchmarks<curandStatePhilox4_32_10_t>(parser, distribution);
|
||||
}
|
||||
else if (engine == "sobol32")
|
||||
{
|
||||
// CHECK: run_benchmarks<hiprandStateSobol32_t>(parser, distribution);
|
||||
run_benchmarks<curandStateSobol32_t>(parser, distribution);
|
||||
}
|
||||
else if (engine == "mtgp32")
|
||||
{
|
||||
// CHECK: run_benchmarks<hiprandStateMtgp32_t>(parser, distribution);
|
||||
run_benchmarks<curandStateMtgp32_t>(parser, distribution);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,494 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015 - 2016 Florian Rappl
|
||||
//
|
||||
// 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 file is part of the C++ CmdParser utility.
|
||||
Copyright (c) 2015 - 2016 Florian Rappl
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <functional>
|
||||
|
||||
namespace cli {
|
||||
struct CallbackArgs {
|
||||
const std::vector<std::string>& arguments;
|
||||
std::ostream& output;
|
||||
std::ostream& error;
|
||||
};
|
||||
class Parser {
|
||||
private:
|
||||
class CmdBase {
|
||||
public:
|
||||
explicit CmdBase(const std::string& name, const std::string& alternative,
|
||||
const std::string& description, bool required, bool dominant,
|
||||
bool variadic)
|
||||
: name(name),
|
||||
command(name.size() > 0 ? "-" + name : ""),
|
||||
alternative(alternative.size() > 0 ? "--" + alternative : ""),
|
||||
description(description),
|
||||
required(required),
|
||||
handled(false),
|
||||
arguments({}),
|
||||
dominant(dominant),
|
||||
variadic(variadic) {}
|
||||
|
||||
virtual ~CmdBase() {}
|
||||
|
||||
std::string name;
|
||||
std::string command;
|
||||
std::string alternative;
|
||||
std::string description;
|
||||
bool required;
|
||||
bool handled;
|
||||
std::vector<std::string> arguments;
|
||||
bool const dominant;
|
||||
bool const variadic;
|
||||
|
||||
virtual std::string print_value() const = 0;
|
||||
virtual bool parse(std::ostream& output, std::ostream& error) = 0;
|
||||
|
||||
bool is(const std::string& given) const { return given == command || given == alternative; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ArgumentCountChecker {
|
||||
static constexpr bool Variadic = false;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ArgumentCountChecker<std::vector<T>> {
|
||||
static constexpr bool Variadic = true;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class CmdFunction final : public CmdBase {
|
||||
public:
|
||||
explicit CmdFunction(const std::string& name, const std::string& alternative,
|
||||
const std::string& description, bool required, bool dominant)
|
||||
: CmdBase(name, alternative, description, required, dominant,
|
||||
ArgumentCountChecker<T>::Variadic) {}
|
||||
|
||||
virtual bool parse(std::ostream& output, std::ostream& error) {
|
||||
try {
|
||||
CallbackArgs args{arguments, output, error};
|
||||
value = callback(args);
|
||||
return true;
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::string print_value() const { return ""; }
|
||||
|
||||
std::function<T(CallbackArgs&)> callback;
|
||||
T value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class CmdArgument final : public CmdBase {
|
||||
public:
|
||||
explicit CmdArgument(const std::string& name, const std::string& alternative,
|
||||
const std::string& description, bool required, bool dominant)
|
||||
: CmdBase(name, alternative, description, required, dominant,
|
||||
ArgumentCountChecker<T>::Variadic) {}
|
||||
|
||||
virtual bool parse(std::ostream&, std::ostream&) {
|
||||
try {
|
||||
value = Parser::parse(arguments, value);
|
||||
return true;
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::string print_value() const { return stringify(value); }
|
||||
|
||||
T value;
|
||||
};
|
||||
|
||||
static int parse(const std::vector<std::string>& elements, const int&) {
|
||||
if (elements.size() != 1) throw std::bad_cast();
|
||||
|
||||
return std::stoi(elements[0]);
|
||||
}
|
||||
|
||||
static bool parse(const std::vector<std::string>& elements, const bool& defval) {
|
||||
if (elements.size() != 0)
|
||||
throw std::runtime_error("A boolean command line parameter cannot have any arguments.");
|
||||
|
||||
return !defval;
|
||||
}
|
||||
|
||||
static double parse(const std::vector<std::string>& elements, const double&) {
|
||||
if (elements.size() != 1) throw std::bad_cast();
|
||||
|
||||
return std::stod(elements[0]);
|
||||
}
|
||||
|
||||
static float parse(const std::vector<std::string>& elements, const float&) {
|
||||
if (elements.size() != 1) throw std::bad_cast();
|
||||
|
||||
return std::stof(elements[0]);
|
||||
}
|
||||
|
||||
static long double parse(const std::vector<std::string>& elements, const long double&) {
|
||||
if (elements.size() != 1) throw std::bad_cast();
|
||||
|
||||
return std::stold(elements[0]);
|
||||
}
|
||||
|
||||
static unsigned int parse(const std::vector<std::string>& elements, const unsigned int&) {
|
||||
if (elements.size() != 1) throw std::bad_cast();
|
||||
|
||||
return static_cast<unsigned int>(std::stoul(elements[0]));
|
||||
}
|
||||
|
||||
static unsigned long parse(const std::vector<std::string>& elements, const unsigned long&) {
|
||||
if (elements.size() != 1) throw std::bad_cast();
|
||||
|
||||
return std::stoul(elements[0]);
|
||||
}
|
||||
|
||||
static unsigned long long parse(const std::vector<std::string>& elements,
|
||||
const unsigned long long&) {
|
||||
if (elements.size() != 1) throw std::bad_cast();
|
||||
|
||||
return std::stoull(elements[0]);
|
||||
}
|
||||
|
||||
static long parse(const std::vector<std::string>& elements, const long&) {
|
||||
if (elements.size() != 1) throw std::bad_cast();
|
||||
|
||||
return std::stol(elements[0]);
|
||||
}
|
||||
|
||||
static std::string parse(const std::vector<std::string>& elements, const std::string&) {
|
||||
if (elements.size() != 1) throw std::bad_cast();
|
||||
|
||||
return elements[0];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static std::vector<T> parse(const std::vector<std::string>& elements, const std::vector<T>&) {
|
||||
const T defval = T();
|
||||
std::vector<T> values{};
|
||||
std::vector<std::string> buffer(1);
|
||||
|
||||
for (const auto& element : elements) {
|
||||
buffer[0] = element;
|
||||
values.push_back(parse(buffer, defval));
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static std::string stringify(const T& value) {
|
||||
return std::to_string(value);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static std::string stringify(const std::vector<T>& values) {
|
||||
std::stringstream ss{};
|
||||
ss << "[ ";
|
||||
|
||||
for (const auto& value : values) {
|
||||
ss << stringify(value) << " ";
|
||||
}
|
||||
|
||||
ss << "]";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
static std::string stringify(const std::string& str) { return str; }
|
||||
|
||||
public:
|
||||
explicit Parser(int argc, const char** argv) : _appname(argv[0]) {
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
_arguments.push_back(argv[i]);
|
||||
}
|
||||
enable_help();
|
||||
}
|
||||
|
||||
explicit Parser(int argc, char** argv) : _appname(argv[0]) {
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
_arguments.push_back(argv[i]);
|
||||
}
|
||||
enable_help();
|
||||
}
|
||||
|
||||
~Parser() {
|
||||
for (int i = 0, n = _commands.size(); i < n; ++i) {
|
||||
delete _commands[i];
|
||||
}
|
||||
}
|
||||
|
||||
bool has_help() const {
|
||||
for (const auto command : _commands) {
|
||||
if (command->name == "h" && command->alternative == "--help") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void enable_help() {
|
||||
set_callback("h", "help", std::function<bool(CallbackArgs&)>([this](CallbackArgs& args) {
|
||||
args.output << this->usage();
|
||||
exit(0);
|
||||
return false;
|
||||
}),
|
||||
"", true);
|
||||
}
|
||||
|
||||
void disable_help() {
|
||||
for (auto command = _commands.begin(); command != _commands.end(); ++command) {
|
||||
if ((*command)->name == "h" && (*command)->alternative == "--help") {
|
||||
_commands.erase(command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void set_default(bool is_required, const std::string& description = "") {
|
||||
auto command = new CmdArgument<T>{"", "", description, is_required, false};
|
||||
_commands.push_back(command);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void set_required(const std::string& name, const std::string& alternative,
|
||||
const std::string& description = "", bool dominant = false) {
|
||||
auto command = new CmdArgument<T>{name, alternative, description, true, dominant};
|
||||
_commands.push_back(command);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void set_optional(const std::string& name, const std::string& alternative, T defaultValue,
|
||||
const std::string& description = "", bool dominant = false) {
|
||||
auto command = new CmdArgument<T>{name, alternative, description, false, dominant};
|
||||
command->value = defaultValue;
|
||||
_commands.push_back(command);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void set_callback(const std::string& name, const std::string& alternative,
|
||||
std::function<T(CallbackArgs&)> callback, const std::string& description = "",
|
||||
bool dominant = false) {
|
||||
auto command = new CmdFunction<T>{name, alternative, description, false, dominant};
|
||||
command->callback = callback;
|
||||
_commands.push_back(command);
|
||||
}
|
||||
|
||||
inline void run_and_exit_if_error() {
|
||||
if (run() == false) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool run() { return run(std::cout, std::cerr); }
|
||||
|
||||
inline bool run(std::ostream& output) { return run(output, std::cerr); }
|
||||
|
||||
bool run(std::ostream& output, std::ostream& error) {
|
||||
if (_arguments.size() > 0) {
|
||||
auto current = find_default();
|
||||
|
||||
for (int i = 0, n = _arguments.size(); i < n; ++i) {
|
||||
auto isarg = _arguments[i].size() > 0 && _arguments[i][0] == '-';
|
||||
auto associated = isarg ? find(_arguments[i]) : nullptr;
|
||||
|
||||
if (associated != nullptr) {
|
||||
current = associated;
|
||||
associated->handled = true;
|
||||
} else if (current == nullptr) {
|
||||
error << no_default();
|
||||
return false;
|
||||
} else {
|
||||
current->arguments.push_back(_arguments[i]);
|
||||
current->handled = true;
|
||||
if (!current->variadic) {
|
||||
// If the current command is not variadic, then no more arguments
|
||||
// should be added to it. In this case, switch back to the default
|
||||
// command.
|
||||
current = find_default();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// First, parse dominant arguments since they succeed even if required
|
||||
// arguments are missing.
|
||||
for (auto command : _commands) {
|
||||
if (command->handled && command->dominant && !command->parse(output, error)) {
|
||||
error << howto_use(command);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Next, check for any missing arguments.
|
||||
for (auto command : _commands) {
|
||||
if (command->required && !command->handled) {
|
||||
error << howto_required(command);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, parse all remaining arguments.
|
||||
for (auto command : _commands) {
|
||||
if (command->handled && !command->dominant && !command->parse(output, error)) {
|
||||
error << howto_use(command);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get(const std::string& name) const {
|
||||
for (const auto& command : _commands) {
|
||||
if (command->name == name) {
|
||||
auto cmd = dynamic_cast<CmdArgument<T>*>(command);
|
||||
|
||||
if (cmd == nullptr) {
|
||||
throw std::runtime_error("Invalid usage of the parameter " + name +
|
||||
" detected.");
|
||||
}
|
||||
|
||||
return cmd->value;
|
||||
}
|
||||
}
|
||||
|
||||
throw std::runtime_error("The parameter " + name + " could not be found.");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get_if(const std::string& name, std::function<T(T)> callback) const {
|
||||
auto value = get<T>(name);
|
||||
return callback(value);
|
||||
}
|
||||
|
||||
int requirements() const {
|
||||
int count = 0;
|
||||
|
||||
for (const auto& command : _commands) {
|
||||
if (command->required) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int commands() const { return static_cast<int>(_commands.size()); }
|
||||
|
||||
inline const std::string& app_name() const { return _appname; }
|
||||
|
||||
protected:
|
||||
CmdBase* find(const std::string& name) {
|
||||
for (auto command : _commands) {
|
||||
if (command->is(name)) {
|
||||
return command;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CmdBase* find_default() {
|
||||
for (auto command : _commands) {
|
||||
if (command->name == "") {
|
||||
return command;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string usage() const {
|
||||
std::stringstream ss{};
|
||||
ss << "Available parameters:\n\n";
|
||||
|
||||
for (const auto& command : _commands) {
|
||||
ss << " " << command->command << "\t" << command->alternative;
|
||||
|
||||
if (command->required == true) {
|
||||
ss << "\t(required)";
|
||||
}
|
||||
|
||||
ss << "\n " << command->description;
|
||||
|
||||
if (command->required == false) {
|
||||
ss << "\n "
|
||||
<< "This parameter is optional. The default value is '" + command->print_value()
|
||||
<< "'.";
|
||||
}
|
||||
|
||||
ss << "\n\n";
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void print_help(std::stringstream& ss) const {
|
||||
if (has_help()) {
|
||||
ss << "For more help use --help or -h.\n";
|
||||
}
|
||||
}
|
||||
|
||||
std::string howto_required(CmdBase* command) const {
|
||||
std::stringstream ss{};
|
||||
ss << "The parameter " << command->name << " is required.\n";
|
||||
ss << command->description << '\n';
|
||||
print_help(ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string howto_use(CmdBase* command) const {
|
||||
std::stringstream ss{};
|
||||
ss << "The parameter " << command->name << " has invalid arguments.\n";
|
||||
ss << command->description << '\n';
|
||||
print_help(ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string no_default() const {
|
||||
std::stringstream ss{};
|
||||
ss << "No default parameter has been specified.\n";
|
||||
ss << "The given argument must be used with a parameter.\n";
|
||||
print_help(ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
const std::string _appname;
|
||||
std::vector<std::string> _arguments;
|
||||
std::vector<CmdBase*> _commands;
|
||||
};
|
||||
} // namespace cli
|
||||
@@ -1,416 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// Taken from: http://docs.nvidia.com/cuda/curand/device-api-overview.html#poisson-api-example
|
||||
/*
|
||||
* This program uses CURAND library for Poisson distribution
|
||||
* to simulate queues in store for 16 hours. It shows the
|
||||
* difference of using 3 different APIs:
|
||||
* - HOST API -arrival of customers is described by Poisson(4)
|
||||
* - SIMPLE DEVICE API -arrival of customers is described by
|
||||
* Poisson(4*(sin(x/100)+1)), where x is number of minutes
|
||||
* from store opening time.
|
||||
* - ROBUST DEVICE API -arrival of customers is described by:
|
||||
* - Poisson(2) for first 3 hours.
|
||||
* - Poisson(1) for second 3 hours.
|
||||
* - Poisson(3) after 6 hours.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda.h>
|
||||
// CHECK: #include <hiprand_kernel.h>
|
||||
#include <curand_kernel.h>
|
||||
// CHECK: #include <hiprand.h>
|
||||
#include <curand.h>
|
||||
|
||||
// CHECK: #define CUDA_CALL(x) do { if((x) != hipSuccess) {
|
||||
#define CUDA_CALL(x) do { if((x) != cudaSuccess) { \
|
||||
printf("Error at %s:%d\n",__FILE__,__LINE__); \
|
||||
return EXIT_FAILURE;}} while(0)
|
||||
// CHECK: #define CURAND_CALL(x) do { if((x)!=HIPRAND_STATUS_SUCCESS) {
|
||||
#define CURAND_CALL(x) do { if((x)!=CURAND_STATUS_SUCCESS) { \
|
||||
printf("Error at %s:%d\n",__FILE__,__LINE__);\
|
||||
return EXIT_FAILURE;}} while(0)
|
||||
|
||||
|
||||
#define HOURS 16
|
||||
#define OPENING_HOUR 7
|
||||
#define CLOSING_HOUR (OPENING_HOUR + HOURS)
|
||||
|
||||
#define access_2D(type, ptr, row, column, pitch)\
|
||||
*((type*)((char*)ptr + (row) * pitch) + column)
|
||||
|
||||
enum API_TYPE {
|
||||
HOST_API = 0,
|
||||
SIMPLE_DEVICE_API = 1,
|
||||
ROBUST_DEVICE_API = 2,
|
||||
};
|
||||
|
||||
/* global variables */
|
||||
API_TYPE api;
|
||||
int report_break;
|
||||
int cashiers_load_h[HOURS];
|
||||
__constant__ int cashiers_load[HOURS];
|
||||
// CHECK: __global__ void setup_kernel(hiprandState *state)
|
||||
__global__ void setup_kernel(curandState *state)
|
||||
{
|
||||
int id = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
/* Each thread gets same seed, a different sequence
|
||||
number, no offset */
|
||||
// CHECK: hiprand_init(1234, id, 0, &state[id]);
|
||||
curand_init(1234, id, 0, &state[id]);
|
||||
}
|
||||
|
||||
__inline__ __device__
|
||||
void update_queue(int id, int min, unsigned int new_customers,
|
||||
unsigned int &queue_length,
|
||||
unsigned int *queue_lengths, size_t pitch)
|
||||
{
|
||||
int balance;
|
||||
balance = new_customers - 2 * cashiers_load[(min-1)/60];
|
||||
if (balance + (int)queue_length <= 0){
|
||||
queue_length = 0;
|
||||
}else{
|
||||
queue_length += balance;
|
||||
}
|
||||
/* Store results */
|
||||
access_2D(unsigned int, queue_lengths, min-1, id, pitch)
|
||||
= queue_length;
|
||||
}
|
||||
|
||||
// CHECK: __global__ void simple_device_API_kernel(hiprandState *state,
|
||||
__global__ void simple_device_API_kernel(curandState *state,
|
||||
unsigned int *queue_lengths, size_t pitch)
|
||||
{
|
||||
int id = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
unsigned int new_customers;
|
||||
unsigned int queue_length = 0;
|
||||
/* Copy state to local memory for efficiency */
|
||||
// CHECK: hiprandState localState = state[id];
|
||||
curandState localState = state[id];
|
||||
/* Simulate queue in time */
|
||||
for(int min = 1; min <= 60 * HOURS; min++) {
|
||||
/* Draw number of new customers depending on API */
|
||||
// CHECK: new_customers = hiprand_poisson(&localState,
|
||||
new_customers = curand_poisson(&localState,
|
||||
4*(sin((float)min/100.0)+1));
|
||||
/* Update queue */
|
||||
update_queue(id, min, new_customers, queue_length,
|
||||
queue_lengths, pitch);
|
||||
}
|
||||
/* Copy state back to global memory */
|
||||
state[id] = localState;
|
||||
}
|
||||
|
||||
|
||||
__global__ void host_API_kernel(unsigned int *poisson_numbers,
|
||||
unsigned int *queue_lengths, size_t pitch)
|
||||
{
|
||||
int id = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
unsigned int new_customers;
|
||||
unsigned int queue_length = 0;
|
||||
/* Simulate queue in time */
|
||||
for(int min = 1; min <= 60 * HOURS; min++) {
|
||||
/* Get random number from global memory */
|
||||
new_customers = poisson_numbers
|
||||
[blockDim.x * gridDim.x * (min -1) + id];
|
||||
/* Update queue */
|
||||
update_queue(id, min, new_customers, queue_length,
|
||||
queue_lengths, pitch);
|
||||
}
|
||||
}
|
||||
// CHECK: __global__ void robust_device_API_kernel(hiprandState *state,
|
||||
// CHECK: hiprandDiscreteDistribution_t poisson_1,
|
||||
// CHECK: hiprandDiscreteDistribution_t poisson_2,
|
||||
// CHECK: hiprandDiscreteDistribution_t poisson_3,
|
||||
__global__ void robust_device_API_kernel(curandState *state,
|
||||
curandDiscreteDistribution_t poisson_1,
|
||||
curandDiscreteDistribution_t poisson_2,
|
||||
curandDiscreteDistribution_t poisson_3,
|
||||
unsigned int *queue_lengths, size_t pitch)
|
||||
{
|
||||
int id = threadIdx.x + blockIdx.x * 64;
|
||||
unsigned int new_customers;
|
||||
unsigned int queue_length = 0;
|
||||
/* Copy state to local memory for efficiency */
|
||||
// CHECK: hiprandState localState = state[id];
|
||||
curandState localState = state[id];
|
||||
/* Simulate queue in time */
|
||||
/* first 3 hours */
|
||||
for(int min = 1; min <= 60 * 3; min++) {
|
||||
/* draw number of new customers depending on API */
|
||||
new_customers =
|
||||
// CHECK: hiprand_discrete(&localState, poisson_2);
|
||||
curand_discrete(&localState, poisson_2);
|
||||
/* Update queue */
|
||||
update_queue(id, min, new_customers, queue_length,
|
||||
queue_lengths, pitch);
|
||||
}
|
||||
/* second 3 hours */
|
||||
for(int min = 60 * 3 + 1; min <= 60 * 6; min++) {
|
||||
/* draw number of new customers depending on API */
|
||||
new_customers =
|
||||
// CHECK: hiprand_discrete(&localState, poisson_1);
|
||||
curand_discrete(&localState, poisson_1);
|
||||
/* Update queue */
|
||||
update_queue(id, min, new_customers, queue_length,
|
||||
queue_lengths, pitch);
|
||||
}
|
||||
/* after 6 hours */
|
||||
for(int min = 60 * 6 + 1; min <= 60 * HOURS; min++) {
|
||||
/* draw number of new customers depending on API */
|
||||
new_customers =
|
||||
// CHECK: hiprand_discrete(&localState, poisson_3);
|
||||
curand_discrete(&localState, poisson_3);
|
||||
/* Update queue */
|
||||
update_queue(id, min, new_customers, queue_length,
|
||||
queue_lengths, pitch);
|
||||
}
|
||||
/* Copy state back to global memory */
|
||||
state[id] = localState;
|
||||
}
|
||||
|
||||
/* Set time intervals between reports */
|
||||
void report_settings()
|
||||
{
|
||||
do{
|
||||
printf("Set time intervals between queue reports");
|
||||
printf("(in minutes > 0)\n");
|
||||
if (scanf("%d", &report_break) == 0) continue;
|
||||
}while(report_break <= 0);
|
||||
}
|
||||
|
||||
|
||||
/* Set number of cashiers each hour */
|
||||
void add_cachiers(int *cashiers_load)
|
||||
{
|
||||
int i, min, max, begin, end;
|
||||
printf("Cashier serves 2 customers per minute...\n");
|
||||
for (i = 0; i < HOURS; i++){
|
||||
cashiers_load_h[i] = 0;
|
||||
}
|
||||
while (true){
|
||||
printf("Adding cashier...\n");
|
||||
min = OPENING_HOUR;
|
||||
max = CLOSING_HOUR-1;
|
||||
do{
|
||||
printf("Set hour that cahier comes (%d-%d)",
|
||||
min, max);
|
||||
printf(" [type 0 to finish adding cashiers]\n");
|
||||
if (scanf("%d", &begin) == 0) continue;
|
||||
}while (begin > max || (begin < min && begin != 0));
|
||||
if (begin == 0) break;
|
||||
min = begin+1;
|
||||
max = CLOSING_HOUR;
|
||||
do{
|
||||
printf("Set hour that cahier leaves (%d-%d)",
|
||||
min, max);
|
||||
printf(" [type 0 to finish adding cashiers]\n");
|
||||
if (scanf("%d", &end) == 0) continue;
|
||||
}while (end > max || (end < min && end != 0));
|
||||
if (end == 0) break;
|
||||
for (i = begin - OPENING_HOUR;
|
||||
i < end - OPENING_HOUR; i++){
|
||||
cashiers_load_h[i]++;
|
||||
}
|
||||
}
|
||||
for (i = OPENING_HOUR; i < CLOSING_HOUR; i++){
|
||||
printf("\n%2d:00 - %2d:00 %d cashier",
|
||||
i, i+1, cashiers_load_h[i-OPENING_HOUR]);
|
||||
if (cashiers_load[i-OPENING_HOUR] != 1) printf("s");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* Set API type */
|
||||
API_TYPE set_API_type()
|
||||
{
|
||||
printf("Choose API type:\n");
|
||||
int choose;
|
||||
do{
|
||||
printf("type 1 for HOST API\n");
|
||||
printf("type 2 for SIMPLE DEVICE API\n");
|
||||
printf("type 3 for ROBUST DEVICE API\n");
|
||||
if (scanf("%d", &choose) == 0) continue;
|
||||
}while( choose < 1 || choose > 3);
|
||||
switch(choose){
|
||||
case 1: return HOST_API;
|
||||
case 2: return SIMPLE_DEVICE_API;
|
||||
case 3: return ROBUST_DEVICE_API;
|
||||
default:
|
||||
fprintf(stderr, "wrong API\n");
|
||||
return HOST_API;
|
||||
}
|
||||
}
|
||||
|
||||
void settings()
|
||||
{
|
||||
add_cachiers(cashiers_load);
|
||||
// CHECK: hipMemcpyToSymbol(HIP_SYMBOL("cashiers_load"), cashiers_load_h,
|
||||
// CHECK: HOURS * sizeof(int), 0, hipMemcpyHostToDevice);
|
||||
cudaMemcpyToSymbol("cashiers_load", cashiers_load_h,
|
||||
HOURS * sizeof(int), 0, cudaMemcpyHostToDevice);
|
||||
report_settings();
|
||||
api = set_API_type();
|
||||
}
|
||||
|
||||
void print_statistics(unsigned int *hostResults, size_t pitch)
|
||||
{
|
||||
int min, i, hour, minute;
|
||||
unsigned int sum;
|
||||
for(min = report_break; min <= 60 * HOURS;
|
||||
min += report_break) {
|
||||
sum = 0;
|
||||
for(i = 0; i < 64 * 64; i++) {
|
||||
sum += access_2D(unsigned int, hostResults,
|
||||
min-1, i, pitch);
|
||||
}
|
||||
hour = OPENING_HOUR + min/60;
|
||||
minute = min%60;
|
||||
printf("%2d:%02d # of waiting customers = %10.4g |",
|
||||
hour, minute, (float)sum/(64.0 * 64.0));
|
||||
printf(" # of cashiers = %d | ",
|
||||
cashiers_load_h[(min-1)/60]);
|
||||
printf("# of new customers/min ~= ");
|
||||
switch (api){
|
||||
case HOST_API:
|
||||
printf("%2.2f\n", 4.0);
|
||||
break;
|
||||
case SIMPLE_DEVICE_API:
|
||||
printf("%2.2f\n",
|
||||
4*(sin((float)min/100.0)+1));
|
||||
break;
|
||||
case ROBUST_DEVICE_API:
|
||||
if (min <= 3 * 60){
|
||||
printf("%2.2f\n", 2.0);
|
||||
}else{
|
||||
if (min <= 6 * 60){
|
||||
printf("%2.2f\n", 1.0);
|
||||
}else{
|
||||
printf("%2.2f\n", 3.0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Wrong API\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int n;
|
||||
size_t pitch;
|
||||
// CHECK: hiprandState *devStates;
|
||||
curandState *devStates;
|
||||
unsigned int *devResults, *hostResults;
|
||||
unsigned int *poisson_numbers_d;
|
||||
// CHECK: hiprandDiscreteDistribution_t poisson_1, poisson_2;
|
||||
// CHECK: hiprandDiscreteDistribution_t poisson_3;
|
||||
// CHECK: hiprandGenerator_t gen;
|
||||
curandDiscreteDistribution_t poisson_1, poisson_2;
|
||||
curandDiscreteDistribution_t poisson_3;
|
||||
curandGenerator_t gen;
|
||||
|
||||
/* Setting cashiers, report and API */
|
||||
settings();
|
||||
|
||||
/* Allocate space for results on device */
|
||||
// CHECK: CUDA_CALL(hipMallocPitch((void **)&devResults, &pitch,
|
||||
CUDA_CALL(cudaMallocPitch((void **)&devResults, &pitch,
|
||||
64 * 64 * sizeof(unsigned int), 60 * HOURS));
|
||||
|
||||
/* Allocate space for results on host */
|
||||
hostResults = (unsigned int *)calloc(pitch * 60 * HOURS,
|
||||
sizeof(unsigned int));
|
||||
|
||||
/* Allocate space for prng states on device */
|
||||
// CHECK: CUDA_CALL(hipMalloc((void **)&devStates, 64 * 64 *
|
||||
// CHECK: sizeof(hiprandState)));
|
||||
CUDA_CALL(cudaMalloc((void **)&devStates, 64 * 64 *
|
||||
sizeof(curandState)));
|
||||
|
||||
/* Setup prng states */
|
||||
if (api != HOST_API){
|
||||
// CHECK: hipLaunchKernelGGL(setup_kernel, dim3(64), dim3(64), 0, 0, devStates);
|
||||
setup_kernel<<<64, 64>>>(devStates);
|
||||
}
|
||||
/* Simulate queue */
|
||||
switch (api){
|
||||
case HOST_API:
|
||||
/* Create pseudo-random number generator */
|
||||
// CHECK: CURAND_CALL(hiprandCreateGenerator(&gen,
|
||||
// CHECK: HIPRAND_RNG_PSEUDO_DEFAULT));
|
||||
CURAND_CALL(curandCreateGenerator(&gen,
|
||||
CURAND_RNG_PSEUDO_DEFAULT));
|
||||
/* Set seed */
|
||||
// CHECK: CURAND_CALL(hiprandSetPseudoRandomGeneratorSeed(
|
||||
CURAND_CALL(curandSetPseudoRandomGeneratorSeed(
|
||||
gen, 1234ULL));
|
||||
/* compute n */
|
||||
n = 64 * 64 * HOURS * 60;
|
||||
/* Allocate n unsigned ints on device */
|
||||
// CHECK: CUDA_CALL(hipMalloc((void **)&poisson_numbers_d,
|
||||
CUDA_CALL(cudaMalloc((void **)&poisson_numbers_d,
|
||||
n * sizeof(unsigned int)));
|
||||
/* Generate n unsigned ints on device */
|
||||
// CHECK: CURAND_CALL(hiprandGeneratePoisson(gen,
|
||||
CURAND_CALL(curandGeneratePoisson(gen,
|
||||
poisson_numbers_d, n, 4.0));
|
||||
// CHECK: hipLaunchKernelGGL(host_API_kernel, dim3(64), dim3(64), 0, 0, poisson_numbers_d,
|
||||
host_API_kernel<<<64, 64>>>(poisson_numbers_d,
|
||||
devResults, pitch);
|
||||
/* Cleanup */
|
||||
// CHECK: CURAND_CALL(hiprandDestroyGenerator(gen));
|
||||
CURAND_CALL(curandDestroyGenerator(gen));
|
||||
break;
|
||||
case SIMPLE_DEVICE_API:
|
||||
// CHECK: hipLaunchKernelGGL(simple_device_API_kernel, dim3(64), dim3(64), 0, 0, devStates,
|
||||
simple_device_API_kernel<<<64, 64>>>(devStates,
|
||||
devResults, pitch);
|
||||
break;
|
||||
case ROBUST_DEVICE_API:
|
||||
/* Create histograms for Poisson(1) */
|
||||
// CHECK: CURAND_CALL(hiprandCreatePoissonDistribution(1.0,
|
||||
CURAND_CALL(curandCreatePoissonDistribution(1.0,
|
||||
&poisson_1));
|
||||
/* Create histograms for Poisson(2) */
|
||||
// CHECK: CURAND_CALL(hiprandCreatePoissonDistribution(2.0,
|
||||
CURAND_CALL(curandCreatePoissonDistribution(2.0,
|
||||
&poisson_2));
|
||||
/* Create histograms for Poisson(3) */
|
||||
// CHECK: CURAND_CALL(hiprandCreatePoissonDistribution(3.0,
|
||||
CURAND_CALL(curandCreatePoissonDistribution(3.0,
|
||||
&poisson_3));
|
||||
// CHECK: hipLaunchKernelGGL(robust_device_API_kernel, dim3(64), dim3(64), 0, 0, devStates,
|
||||
robust_device_API_kernel<<<64, 64>>>(devStates,
|
||||
poisson_1, poisson_2, poisson_3,
|
||||
devResults, pitch);
|
||||
/* Cleanup */
|
||||
// CHECK: CURAND_CALL(hiprandDestroyDistribution(poisson_1));
|
||||
// CHECK: CURAND_CALL(hiprandDestroyDistribution(poisson_2));
|
||||
// CHECK: CURAND_CALL(hiprandDestroyDistribution(poisson_3));
|
||||
CURAND_CALL(curandDestroyDistribution(poisson_1));
|
||||
CURAND_CALL(curandDestroyDistribution(poisson_2));
|
||||
CURAND_CALL(curandDestroyDistribution(poisson_3));
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Wrong API\n");
|
||||
}
|
||||
/* Copy device memory to host */
|
||||
// CHECK: CUDA_CALL(hipMemcpy2D(hostResults, pitch, devResults,
|
||||
// CHECK: 60 * HOURS, hipMemcpyDeviceToHost));
|
||||
CUDA_CALL(cudaMemcpy2D(hostResults, pitch, devResults,
|
||||
pitch, 64 * 64 * sizeof(unsigned int),
|
||||
60 * HOURS, cudaMemcpyDeviceToHost));
|
||||
/* Show result */
|
||||
print_statistics(hostResults, pitch);
|
||||
/* Cleanup */
|
||||
// CHECK: CUDA_CALL(hipFree(devStates));
|
||||
// CHECK: CUDA_CALL(hipFree(devResults));
|
||||
CUDA_CALL(cudaFree(devStates));
|
||||
CUDA_CALL(cudaFree(devResults));
|
||||
free(hostResults);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -1,367 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include "hipsparse.h"
|
||||
#include "cusparse.h"
|
||||
|
||||
// CHECK: if (y) hipFree(y);
|
||||
// CHECK: if (z) hipFree(z);
|
||||
// CHECK: if (xInd) hipFree(xInd);
|
||||
// CHECK: if (xVal) hipFree(xVal);
|
||||
// CHECK: if (csrRowPtr) hipFree(csrRowPtr);
|
||||
// CHECK: if (cooRowIndex) hipFree(cooRowIndex);
|
||||
// CHECK: if (cooColIndex) hipFree(cooColIndex);
|
||||
// CHECK: if (cooVal) hipFree(cooVal);
|
||||
// CHECK: if (descr) hipsparseDestroyMatDescr(descr);
|
||||
// CHECK: if (handle) hipsparseDestroy(handle);
|
||||
// CHECK: hipDeviceReset();
|
||||
#define CLEANUP(s) \
|
||||
do { \
|
||||
printf ("%s\n", s); \
|
||||
if (yHostPtr) free(yHostPtr); \
|
||||
if (zHostPtr) free(zHostPtr); \
|
||||
if (xIndHostPtr) free(xIndHostPtr); \
|
||||
if (xValHostPtr) free(xValHostPtr); \
|
||||
if (cooRowIndexHostPtr) free(cooRowIndexHostPtr);\
|
||||
if (cooColIndexHostPtr) free(cooColIndexHostPtr);\
|
||||
if (cooValHostPtr) free(cooValHostPtr); \
|
||||
if (y) cudaFree(y); \
|
||||
if (z) cudaFree(z); \
|
||||
if (xInd) cudaFree(xInd); \
|
||||
if (xVal) cudaFree(xVal); \
|
||||
if (csrRowPtr) cudaFree(csrRowPtr); \
|
||||
if (cooRowIndex) cudaFree(cooRowIndex); \
|
||||
if (cooColIndex) cudaFree(cooColIndex); \
|
||||
if (cooVal) cudaFree(cooVal); \
|
||||
if (descr) cusparseDestroyMatDescr(descr);\
|
||||
if (handle) cusparseDestroy(handle); \
|
||||
cudaDeviceReset(); \
|
||||
fflush (stdout); \
|
||||
} while (0)
|
||||
|
||||
int main(){
|
||||
// CHECK: hipError_t cudaStat1,cudaStat2,cudaStat3,cudaStat4,cudaStat5,cudaStat6;
|
||||
cudaError_t cudaStat1,cudaStat2,cudaStat3,cudaStat4,cudaStat5,cudaStat6;
|
||||
// CHECK: hipsparseStatus_t status;
|
||||
cusparseStatus_t status;
|
||||
// CHECK: hipsparseHandle_t handle=0;
|
||||
cusparseHandle_t handle=0;
|
||||
// CHECK: hipsparseMatDescr_t descr=0;
|
||||
cusparseMatDescr_t descr=0;
|
||||
int * cooRowIndexHostPtr=0;
|
||||
int * cooColIndexHostPtr=0;
|
||||
double * cooValHostPtr=0;
|
||||
int * cooRowIndex=0;
|
||||
int * cooColIndex=0;
|
||||
double * cooVal=0;
|
||||
int * xIndHostPtr=0;
|
||||
double * xValHostPtr=0;
|
||||
double * yHostPtr=0;
|
||||
int * xInd=0;
|
||||
double * xVal=0;
|
||||
double * y=0;
|
||||
int * csrRowPtr=0;
|
||||
double * zHostPtr=0;
|
||||
double * z=0;
|
||||
int n, nnz, nnz_vector;
|
||||
double dzero =0.0;
|
||||
double dtwo =2.0;
|
||||
double dthree=3.0;
|
||||
double dfive =5.0;
|
||||
printf("testing example\n");
|
||||
/* create the following sparse test matrix in COO format */
|
||||
/* |1.0 2.0 3.0|
|
||||
| 4.0 |
|
||||
|5.0 6.0 7.0|
|
||||
| 8.0 9.0| */
|
||||
n=4; nnz=9;
|
||||
cooRowIndexHostPtr = (int *) malloc(nnz*sizeof(cooRowIndexHostPtr[0]));
|
||||
cooColIndexHostPtr = (int *) malloc(nnz*sizeof(cooColIndexHostPtr[0]));
|
||||
cooValHostPtr = (double *)malloc(nnz*sizeof(cooValHostPtr[0]));
|
||||
if ((!cooRowIndexHostPtr) || (!cooColIndexHostPtr) || (!cooValHostPtr)){
|
||||
CLEANUP("Host malloc failed (matrix)");
|
||||
return 1;
|
||||
}
|
||||
cooRowIndexHostPtr[0]=0; cooColIndexHostPtr[0]=0; cooValHostPtr[0]=1.0;
|
||||
cooRowIndexHostPtr[1]=0; cooColIndexHostPtr[1]=2; cooValHostPtr[1]=2.0;
|
||||
cooRowIndexHostPtr[2]=0; cooColIndexHostPtr[2]=3; cooValHostPtr[2]=3.0;
|
||||
cooRowIndexHostPtr[3]=1; cooColIndexHostPtr[3]=1; cooValHostPtr[3]=4.0;
|
||||
cooRowIndexHostPtr[4]=2; cooColIndexHostPtr[4]=0; cooValHostPtr[4]=5.0;
|
||||
cooRowIndexHostPtr[5]=2; cooColIndexHostPtr[5]=2; cooValHostPtr[5]=6.0;
|
||||
cooRowIndexHostPtr[6]=2; cooColIndexHostPtr[6]=3; cooValHostPtr[6]=7.0;
|
||||
cooRowIndexHostPtr[7]=3; cooColIndexHostPtr[7]=1; cooValHostPtr[7]=8.0;
|
||||
cooRowIndexHostPtr[8]=3; cooColIndexHostPtr[8]=3; cooValHostPtr[8]=9.0;
|
||||
nnz_vector = 3;
|
||||
xIndHostPtr = (int *) malloc(nnz_vector*sizeof(xIndHostPtr[0]));
|
||||
xValHostPtr = (double *)malloc(nnz_vector*sizeof(xValHostPtr[0]));
|
||||
yHostPtr = (double *)malloc(2*n *sizeof(yHostPtr[0]));
|
||||
zHostPtr = (double *)malloc(2*(n+1) *sizeof(zHostPtr[0]));
|
||||
if((!xIndHostPtr) || (!xValHostPtr) || (!yHostPtr) || (!zHostPtr)) {
|
||||
CLEANUP("Host malloc failed (vectors)");
|
||||
return 1;
|
||||
}
|
||||
yHostPtr[0] = 10.0;
|
||||
xIndHostPtr[0]=0;
|
||||
xValHostPtr[0]=100.0;
|
||||
yHostPtr[1] = 20.0;
|
||||
xIndHostPtr[1]=1;
|
||||
xValHostPtr[1]=200.0;
|
||||
yHostPtr[2] = 30.0;
|
||||
yHostPtr[3] = 40.0;
|
||||
xIndHostPtr[2]=3;
|
||||
xValHostPtr[2]=400.0;
|
||||
yHostPtr[4] = 50.0;
|
||||
yHostPtr[5] = 60.0;
|
||||
yHostPtr[6] = 70.0;
|
||||
yHostPtr[7] = 80.0;
|
||||
/* allocate GPU memory and copy the matrix and vectors into it */
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&cooRowIndex,nnz*sizeof(cooRowIndex[0]));
|
||||
cudaStat1 = cudaMalloc((void**)&cooRowIndex,nnz*sizeof(cooRowIndex[0]));
|
||||
// CHECK: cudaStat2 = hipMalloc((void**)&cooColIndex,nnz*sizeof(cooColIndex[0]));
|
||||
cudaStat2 = cudaMalloc((void**)&cooColIndex,nnz*sizeof(cooColIndex[0]));
|
||||
// CHECK: cudaStat3 = hipMalloc((void**)&cooVal, nnz*sizeof(cooVal[0]));
|
||||
cudaStat3 = cudaMalloc((void**)&cooVal, nnz*sizeof(cooVal[0]));
|
||||
// CHECK: cudaStat4 = hipMalloc((void**)&y, 2*n*sizeof(y[0]));
|
||||
cudaStat4 = cudaMalloc((void**)&y, 2*n*sizeof(y[0]));
|
||||
// CHECK: cudaStat5 = hipMalloc((void**)&xInd,nnz_vector*sizeof(xInd[0]));
|
||||
cudaStat5 = cudaMalloc((void**)&xInd,nnz_vector*sizeof(xInd[0]));
|
||||
// CHECK: cudaStat6 = hipMalloc((void**)&xVal,nnz_vector*sizeof(xVal[0]));
|
||||
cudaStat6 = cudaMalloc((void**)&xVal,nnz_vector*sizeof(xVal[0]));
|
||||
// CHECK: if ((cudaStat1 != hipSuccess) ||
|
||||
// CHECK: (cudaStat2 != hipSuccess) ||
|
||||
// CHECK: (cudaStat3 != hipSuccess) ||
|
||||
// CHECK: (cudaStat4 != hipSuccess) ||
|
||||
// CHECK: (cudaStat5 != hipSuccess) ||
|
||||
// CHECK: (cudaStat6 != hipSuccess)) {
|
||||
if ((cudaStat1 != cudaSuccess) ||
|
||||
(cudaStat2 != cudaSuccess) ||
|
||||
(cudaStat3 != cudaSuccess) ||
|
||||
(cudaStat4 != cudaSuccess) ||
|
||||
(cudaStat5 != cudaSuccess) ||
|
||||
(cudaStat6 != cudaSuccess)) {
|
||||
CLEANUP("Device malloc failed");
|
||||
return 1;
|
||||
}
|
||||
// CHECK: cudaStat1 = hipMemcpy(cooRowIndex, cooRowIndexHostPtr,
|
||||
// CHECK: hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(cooRowIndex, cooRowIndexHostPtr,
|
||||
(size_t)(nnz*sizeof(cooRowIndex[0])),
|
||||
cudaMemcpyHostToDevice);
|
||||
// CHECK: cudaStat2 = hipMemcpy(cooColIndex, cooColIndexHostPtr,
|
||||
// CHECK: hipMemcpyHostToDevice);
|
||||
cudaStat2 = cudaMemcpy(cooColIndex, cooColIndexHostPtr,
|
||||
(size_t)(nnz*sizeof(cooColIndex[0])),
|
||||
cudaMemcpyHostToDevice);
|
||||
// CHECK: cudaStat3 = hipMemcpy(cooVal, cooValHostPtr,
|
||||
// CHECK: hipMemcpyHostToDevice);
|
||||
cudaStat3 = cudaMemcpy(cooVal, cooValHostPtr,
|
||||
(size_t)(nnz*sizeof(cooVal[0])),
|
||||
cudaMemcpyHostToDevice);
|
||||
// CHECK: cudaStat4 = hipMemcpy(y, yHostPtr,
|
||||
// CHECK: hipMemcpyHostToDevice);
|
||||
cudaStat4 = cudaMemcpy(y, yHostPtr,
|
||||
(size_t)(2*n*sizeof(y[0])),
|
||||
cudaMemcpyHostToDevice);
|
||||
// CHECK: cudaStat5 = hipMemcpy(xInd, xIndHostPtr,
|
||||
// CHECK: hipMemcpyHostToDevice);
|
||||
cudaStat5 = cudaMemcpy(xInd, xIndHostPtr,
|
||||
(size_t)(nnz_vector*sizeof(xInd[0])),
|
||||
cudaMemcpyHostToDevice);
|
||||
// CHECK: cudaStat6 = hipMemcpy(xVal, xValHostPtr,
|
||||
// CHECK: hipMemcpyHostToDevice);
|
||||
cudaStat6 = cudaMemcpy(xVal, xValHostPtr,
|
||||
(size_t)(nnz_vector*sizeof(xVal[0])),
|
||||
cudaMemcpyHostToDevice);
|
||||
// CHECK: if ((cudaStat1 != hipSuccess) ||
|
||||
// CHECK: (cudaStat2 != hipSuccess) ||
|
||||
// CHECK: (cudaStat3 != hipSuccess) ||
|
||||
// CHECK: (cudaStat4 != hipSuccess) ||
|
||||
// CHECK: (cudaStat5 != hipSuccess) ||
|
||||
// CHECK: (cudaStat6 != hipSuccess)) {
|
||||
if ((cudaStat1 != cudaSuccess) ||
|
||||
(cudaStat2 != cudaSuccess) ||
|
||||
(cudaStat3 != cudaSuccess) ||
|
||||
(cudaStat4 != cudaSuccess) ||
|
||||
(cudaStat5 != cudaSuccess) ||
|
||||
(cudaStat6 != cudaSuccess)) {
|
||||
CLEANUP("Memcpy from Host to Device failed");
|
||||
return 1;
|
||||
}
|
||||
/* initialize cusparse library */
|
||||
// CHECK: status= hipsparseCreate(&handle);
|
||||
status= cusparseCreate(&handle);
|
||||
// CHECK: if (status != HIPSPARSE_STATUS_SUCCESS) {
|
||||
if (status != CUSPARSE_STATUS_SUCCESS) {
|
||||
CLEANUP("CUSPARSE Library initialization failed");
|
||||
return 1;
|
||||
}
|
||||
/* create and setup matrix descriptor */
|
||||
// CHECK: status= hipsparseCreateMatDescr(&descr);
|
||||
status= cusparseCreateMatDescr(&descr);
|
||||
// CHECK: if (status != HIPSPARSE_STATUS_SUCCESS) {
|
||||
if (status != CUSPARSE_STATUS_SUCCESS) {
|
||||
CLEANUP("Matrix descriptor initialization failed");
|
||||
return 1;
|
||||
}
|
||||
// CHECK: hipsparseSetMatType(descr,HIPSPARSE_MATRIX_TYPE_GENERAL);
|
||||
cusparseSetMatType(descr,CUSPARSE_MATRIX_TYPE_GENERAL);
|
||||
// CHECK: hipsparseSetMatIndexBase(descr,HIPSPARSE_INDEX_BASE_ZERO);
|
||||
cusparseSetMatIndexBase(descr,CUSPARSE_INDEX_BASE_ZERO);
|
||||
/* exercise conversion routines (convert matrix from COO 2 CSR format) */
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&csrRowPtr,(n+1)*sizeof(csrRowPtr[0]));
|
||||
cudaStat1 = cudaMalloc((void**)&csrRowPtr,(n+1)*sizeof(csrRowPtr[0]));
|
||||
// CHECK: if (cudaStat1 != hipSuccess) {
|
||||
if (cudaStat1 != cudaSuccess) {
|
||||
CLEANUP("Device malloc failed (csrRowPtr)");
|
||||
return 1;
|
||||
}
|
||||
status= cusparseXcoo2csr(handle,cooRowIndex,nnz,n,
|
||||
// CHECK: csrRowPtr,HIPSPARSE_INDEX_BASE_ZERO);
|
||||
csrRowPtr,CUSPARSE_INDEX_BASE_ZERO);
|
||||
// CHECK: if (status != HIPSPARSE_STATUS_SUCCESS) {
|
||||
if (status != CUSPARSE_STATUS_SUCCESS) {
|
||||
CLEANUP("Conversion from COO to CSR format failed");
|
||||
return 1;
|
||||
}
|
||||
//csrRowPtr = [0 3 4 7 9]
|
||||
// The following test only works for compute capability 1.3 and above
|
||||
// because it needs double precision.
|
||||
int devId;
|
||||
// CHECK: hipDeviceProp_t prop;
|
||||
cudaDeviceProp prop;
|
||||
// CHECK: hipError_t cudaStat;
|
||||
cudaError_t cudaStat;
|
||||
// CHECK: cudaStat = hipGetDevice(&devId);
|
||||
cudaStat = cudaGetDevice(&devId);
|
||||
// CHECK: if (hipSuccess != cudaStat){
|
||||
if (cudaSuccess != cudaStat){
|
||||
// CLEANUP("hipGetDevice failed");
|
||||
CLEANUP("cudaGetDevice failed");
|
||||
// printf("Error: cudaStat %d, %s\n", cudaStat, hipGetErrorString(cudaStat));
|
||||
printf("Error: cudaStat %d, %s\n", cudaStat, cudaGetErrorString(cudaStat));
|
||||
return 1;
|
||||
}
|
||||
// CHECK: cudaStat = hipGetDeviceProperties( &prop, devId);
|
||||
cudaStat = cudaGetDeviceProperties( &prop, devId);
|
||||
// CHECK: if (hipSuccess != cudaStat) {
|
||||
if (cudaSuccess != cudaStat) {
|
||||
// CHECK: CLEANUP("hipGetDeviceProperties failed");
|
||||
CLEANUP("cudaGetDeviceProperties failed");
|
||||
// CHECK: printf("Error: cudaStat %d, %s\n", cudaStat, hipGetErrorString(cudaStat));
|
||||
printf("Error: cudaStat %d, %s\n", cudaStat, cudaGetErrorString(cudaStat));
|
||||
return 1;
|
||||
}
|
||||
int cc = 100*prop.major + 10*prop.minor;
|
||||
if (cc < 130){
|
||||
CLEANUP("waive the test because only sm13 and above are supported\n");
|
||||
printf("the device has compute capability %d\n", cc);
|
||||
printf("example test WAIVED");
|
||||
return 2;
|
||||
}
|
||||
/* exercise Level 1 routines (scatter vector elements) */
|
||||
// CHECK: status= hipsparseDsctr(handle, nnz_vector, xVal, xInd,
|
||||
// CHECK: &y[n], HIPSPARSE_INDEX_BASE_ZERO);
|
||||
status= cusparseDsctr(handle, nnz_vector, xVal, xInd,
|
||||
&y[n], CUSPARSE_INDEX_BASE_ZERO);
|
||||
// CHECK: if (status != HIPSPARSE_STATUS_SUCCESS) {
|
||||
if (status != CUSPARSE_STATUS_SUCCESS) {
|
||||
CLEANUP("Scatter from sparse to dense vector failed");
|
||||
return 1;
|
||||
}
|
||||
//y = [10 20 30 40 | 100 200 70 400]
|
||||
/* exercise Level 2 routines (csrmv) */
|
||||
// CHECK: status= hipsparseDcsrmv(handle,HIPSPARSE_OPERATION_NON_TRANSPOSE, n, n, nnz,
|
||||
status= cusparseDcsrmv(handle,CUSPARSE_OPERATION_NON_TRANSPOSE, n, n, nnz,
|
||||
&dtwo, descr, cooVal, csrRowPtr, cooColIndex,
|
||||
&y[0], &dthree, &y[n]);
|
||||
// CHECK: if (status != HIPSPARSE_STATUS_SUCCESS) {
|
||||
if (status != CUSPARSE_STATUS_SUCCESS) {
|
||||
CLEANUP("Matrix-vector multiplication failed");
|
||||
return 1;
|
||||
}
|
||||
//y = [10 20 30 40 | 680 760 1230 2240]
|
||||
// CHECK: hipMemcpy(yHostPtr, y, (size_t)(2*n*sizeof(y[0])), hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(yHostPtr, y, (size_t)(2*n*sizeof(y[0])), cudaMemcpyDeviceToHost);
|
||||
/* exercise Level 3 routines (csrmm) */
|
||||
// cudaStat1 = hipMalloc((void**)&z, 2*(n+1)*sizeof(z[0]));
|
||||
cudaStat1 = cudaMalloc((void**)&z, 2*(n+1)*sizeof(z[0]));
|
||||
// CHECK: if (cudaStat1 != hipSuccess) {
|
||||
if (cudaStat1 != cudaSuccess) {
|
||||
CLEANUP("Device malloc failed (z)");
|
||||
return 1;
|
||||
}
|
||||
// CHECK: cudaStat1 = hipMemset((void *)z,0, 2*(n+1)*sizeof(z[0]));
|
||||
cudaStat1 = cudaMemset((void *)z,0, 2*(n+1)*sizeof(z[0]));
|
||||
// CHECK: if (cudaStat1 != hipSuccess) {
|
||||
if (cudaStat1 != cudaSuccess) {
|
||||
CLEANUP("Memset on Device failed");
|
||||
return 1;
|
||||
}
|
||||
// CHECK: status= hipsparseDcsrmm(handle, HIPSPARSE_OPERATION_NON_TRANSPOSE, n, 2, n,
|
||||
status= cusparseDcsrmm(handle, CUSPARSE_OPERATION_NON_TRANSPOSE, n, 2, n,
|
||||
nnz, &dfive, descr, cooVal, csrRowPtr, cooColIndex,
|
||||
y, n, &dzero, z, n+1);
|
||||
// CHECK: if (status != HIPSPARSE_STATUS_SUCCESS) {
|
||||
if (status != CUSPARSE_STATUS_SUCCESS) {
|
||||
CLEANUP("Matrix-matrix multiplication failed");
|
||||
return 1;
|
||||
}
|
||||
/* print final results (z) */
|
||||
// CHECK: cudaStat1 = hipMemcpy(zHostPtr, z,
|
||||
// CHECK: hipMemcpyDeviceToHost);
|
||||
cudaStat1 = cudaMemcpy(zHostPtr, z,
|
||||
(size_t)(2*(n+1)*sizeof(z[0])),
|
||||
cudaMemcpyDeviceToHost);
|
||||
// CHECK: if (cudaStat1 != hipSuccess) {
|
||||
if (cudaStat1 != cudaSuccess) {
|
||||
CLEANUP("Memcpy from Device to Host failed");
|
||||
return 1;
|
||||
}
|
||||
//z = [950 400 2550 2600 0 | 49300 15200 132300 131200 0]
|
||||
/* destroy matrix descriptor */
|
||||
// status = hipsparseDestroyMatDescr(descr);
|
||||
status = cusparseDestroyMatDescr(descr);
|
||||
descr = 0;
|
||||
// CHECK: if (status != HIPSPARSE_STATUS_SUCCESS) {
|
||||
if (status != CUSPARSE_STATUS_SUCCESS) {
|
||||
CLEANUP("Matrix descriptor destruction failed");
|
||||
return 1;
|
||||
}
|
||||
/* destroy handle */
|
||||
// CHECK: status = hipsparseDestroy(handle);
|
||||
status = cusparseDestroy(handle);
|
||||
handle = 0;
|
||||
// CHECK: if (status != HIPSPARSE_STATUS_SUCCESS) {
|
||||
if (status != CUSPARSE_STATUS_SUCCESS) {
|
||||
CLEANUP("CUSPARSE Library release of resources failed");
|
||||
return 1;
|
||||
}
|
||||
/* check the results */
|
||||
// Notice that CLEANUP() contains a call to cusparseDestroy(handle)
|
||||
if ((zHostPtr[0] != 950.0) ||
|
||||
(zHostPtr[1] != 400.0) ||
|
||||
(zHostPtr[2] != 2550.0) ||
|
||||
(zHostPtr[3] != 2600.0) ||
|
||||
(zHostPtr[4] != 0.0) ||
|
||||
(zHostPtr[5] != 49300.0) ||
|
||||
(zHostPtr[6] != 15200.0) ||
|
||||
(zHostPtr[7] != 132300.0) ||
|
||||
(zHostPtr[8] != 131200.0) ||
|
||||
(zHostPtr[9] != 0.0) ||
|
||||
(yHostPtr[0] != 10.0) ||
|
||||
(yHostPtr[1] != 20.0) ||
|
||||
(yHostPtr[2] != 30.0) ||
|
||||
(yHostPtr[3] != 40.0) ||
|
||||
(yHostPtr[4] != 680.0) ||
|
||||
(yHostPtr[5] != 760.0) ||
|
||||
(yHostPtr[6] != 1230.0) ||
|
||||
(yHostPtr[7] != 2240.0)) {
|
||||
CLEANUP("example test FAILED");
|
||||
return 1;
|
||||
} else {
|
||||
CLEANUP("example test PASSED");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include <hipblas.h>
|
||||
#include <cublas_v2.h>
|
||||
// CHECK: #include "hipsparse.h"
|
||||
#include "cusparse.h"
|
||||
|
||||
void printMatrix(int m, int n, const double*A, int lda, const char* name)
|
||||
{
|
||||
for(int row = 0 ; row < m ; row++){
|
||||
for(int col = 0 ; col < n ; col++){
|
||||
double Areg = A[row + col*lda];
|
||||
printf("%s(%d,%d) = %f\n", name, row+1, col+1, Areg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
// CHECK: hipblasHandle_t cublasH = NULL;
|
||||
cublasHandle_t cublasH = NULL;
|
||||
// CHECK: hipsparseHandle_t cusparseH = NULL;
|
||||
cusparseHandle_t cusparseH = NULL;
|
||||
// CHECK: hipStream_t stream = NULL;
|
||||
cudaStream_t stream = NULL;
|
||||
// CHECK: hipsparseMatDescr_t descrA = NULL;
|
||||
cusparseMatDescr_t descrA = NULL;
|
||||
// CHECK: hipblasStatus_t cublasStat = HIPBLAS_STATUS_SUCCESS;
|
||||
cublasStatus_t cublasStat = CUBLAS_STATUS_SUCCESS;
|
||||
// CHECK: hipsparseStatus_t cusparseStat = HIPSPARSE_STATUS_SUCCESS;
|
||||
cusparseStatus_t cusparseStat = CUSPARSE_STATUS_SUCCESS;
|
||||
// CHECK: hipError_t cudaStat1 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat2 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat3 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat4 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat5 = hipSuccess;
|
||||
cudaError_t cudaStat1 = cudaSuccess;
|
||||
cudaError_t cudaStat2 = cudaSuccess;
|
||||
cudaError_t cudaStat3 = cudaSuccess;
|
||||
cudaError_t cudaStat4 = cudaSuccess;
|
||||
cudaError_t cudaStat5 = cudaSuccess;
|
||||
const int n = 4;
|
||||
const int nnzA = 9;
|
||||
/*
|
||||
* | 1 0 2 3 |
|
||||
* | 0 4 0 0 |
|
||||
* A = | 5 0 6 7 |
|
||||
* | 0 8 0 9 |
|
||||
*
|
||||
* eigevales are { -0.5311, 7.5311, 9.0000, 4.0000 }
|
||||
*
|
||||
* The largest eigenvaluse is 9 and corresponding eigenvector is
|
||||
*
|
||||
* | 0.3029 |
|
||||
* v = | 0 |
|
||||
* | 0.9350 |
|
||||
* | 0.1844 |
|
||||
*/
|
||||
const int csrRowPtrA[n+1] = { 0, 3, 4, 7, 9 };
|
||||
const int csrColIndA[nnzA] = {0, 2, 3, 1, 0, 2, 3, 1, 3 };
|
||||
const double csrValA[nnzA] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 };
|
||||
const double lambda_exact[n] = { 9.0000, 7.5311, 4.0000, -0.5311 };
|
||||
const double x0[n] = {1.0, 2.0, 3.0, 4.0 }; /* initial guess */
|
||||
double x[n]; /* numerical eigenvector */
|
||||
|
||||
int *d_csrRowPtrA = NULL;
|
||||
int *d_csrColIndA = NULL;
|
||||
double *d_csrValA = NULL;
|
||||
|
||||
double *d_x = NULL; /* eigenvector */
|
||||
double *d_y = NULL; /* workspace */
|
||||
|
||||
const double tol = 1.e-6;
|
||||
const int max_ites = 30;
|
||||
|
||||
const double h_one = 1.0;
|
||||
const double h_zero = 0.0;
|
||||
|
||||
printf("example of csrmv_mp \n");
|
||||
printf("tol = %E \n", tol);
|
||||
printf("max. iterations = %d \n", max_ites);
|
||||
|
||||
printf("1st eigenvaluse is %f\n", lambda_exact[0] );
|
||||
printf("2nd eigenvaluse is %f\n", lambda_exact[1] );
|
||||
|
||||
double alpha = lambda_exact[1]/lambda_exact[0] ;
|
||||
printf("convergence rate is %f\n", alpha );
|
||||
|
||||
double est_iterations = log(tol)/log(alpha);
|
||||
printf("# of iterations required is %d\n", (int)ceil(est_iterations));
|
||||
|
||||
// step 1: create cublas/cusparse handle, bind a stream
|
||||
// CHECK: cudaStat1 = hipStreamCreateWithFlags(&stream, hipStreamNonBlocking);
|
||||
cudaStat1 = cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cublasStat = hipblasCreate(&cublasH);
|
||||
cublasStat = cublasCreate(&cublasH);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
// CHECK: cublasStat = hipblasSetStream(cublasH, stream);
|
||||
cublasStat = cublasSetStream(cublasH, stream);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
// CHECK: cusparseStat = hipsparseCreate(&cusparseH);
|
||||
cusparseStat = cusparseCreate(&cusparseH);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == cusparseStat);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == cusparseStat);
|
||||
// CHECK: cusparseStat = hipsparseSetStream(cusparseH, stream);
|
||||
cusparseStat = cusparseSetStream(cusparseH, stream);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == cusparseStat);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == cusparseStat);
|
||||
|
||||
// step 2: configuration of matrix A
|
||||
// CHECK: cusparseStat = hipsparseCreateMatDescr(&descrA);
|
||||
cusparseStat = cusparseCreateMatDescr(&descrA);
|
||||
// assert(HIPSPARSE_STATUS_SUCCESS == cusparseStat);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == cusparseStat);
|
||||
// CHECK: hipsparseSetMatIndexBase(descrA,HIPSPARSE_INDEX_BASE_ZERO);
|
||||
cusparseSetMatIndexBase(descrA,CUSPARSE_INDEX_BASE_ZERO);
|
||||
// CHECK: hipsparseSetMatType(descrA, HIPSPARSE_MATRIX_TYPE_GENERAL );
|
||||
cusparseSetMatType(descrA, CUSPARSE_MATRIX_TYPE_GENERAL );
|
||||
|
||||
// step 3: copy A and x0 to device
|
||||
// CHECK: cudaStat1 = hipMalloc ((void**)&d_csrRowPtrA, sizeof(int) * (n+1) );
|
||||
cudaStat1 = cudaMalloc ((void**)&d_csrRowPtrA, sizeof(int) * (n+1) );
|
||||
// CHECK: cudaStat2 = hipMalloc ((void**)&d_csrColIndA, sizeof(int) * nnzA );
|
||||
cudaStat2 = cudaMalloc ((void**)&d_csrColIndA, sizeof(int) * nnzA );
|
||||
// CHECK: cudaStat3 = hipMalloc ((void**)&d_csrValA , sizeof(double) * nnzA );
|
||||
cudaStat3 = cudaMalloc ((void**)&d_csrValA , sizeof(double) * nnzA );
|
||||
// CHECK: cudaStat4 = hipMalloc ((void**)&d_x , sizeof(double) * n );
|
||||
cudaStat4 = cudaMalloc ((void**)&d_x , sizeof(double) * n );
|
||||
// CHECK: cudaStat5 = hipMalloc ((void**)&d_y , sizeof(double) * n );
|
||||
cudaStat5 = cudaMalloc ((void**)&d_y , sizeof(double) * n );
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
// CHECK: assert(hipSuccess == cudaStat2);
|
||||
// CHECK: assert(hipSuccess == cudaStat3);
|
||||
// CHECK: assert(hipSuccess == cudaStat4);
|
||||
// CHECK: assert(hipSuccess == cudaStat5);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat2);
|
||||
assert(cudaSuccess == cudaStat3);
|
||||
assert(cudaSuccess == cudaStat4);
|
||||
assert(cudaSuccess == cudaStat5);
|
||||
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_csrRowPtrA, csrRowPtrA, sizeof(int) * (n+1) , hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_csrRowPtrA, csrRowPtrA, sizeof(int) * (n+1) , cudaMemcpyHostToDevice);
|
||||
// CHECK: cudaStat2 = hipMemcpy(d_csrColIndA, csrColIndA, sizeof(int) * nnzA , hipMemcpyHostToDevice);
|
||||
cudaStat2 = cudaMemcpy(d_csrColIndA, csrColIndA, sizeof(int) * nnzA , cudaMemcpyHostToDevice);
|
||||
// CHECK: cudaStat3 = hipMemcpy(d_csrValA , csrValA , sizeof(double) * nnzA , hipMemcpyHostToDevice);
|
||||
cudaStat3 = cudaMemcpy(d_csrValA , csrValA , sizeof(double) * nnzA , cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: assert(hipSuccess == cudaStat2);
|
||||
assert(cudaSuccess == cudaStat2);
|
||||
// CHECK: assert(hipSuccess == cudaStat3);
|
||||
assert(cudaSuccess == cudaStat3);
|
||||
|
||||
// step 4: power method
|
||||
double lambda = 0.0;
|
||||
double lambda_next = 0.0;
|
||||
|
||||
// 4.1: initial guess x0
|
||||
cudaStat1 = cudaMemcpy(d_x, x0, sizeof(double) * n, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
for(int ite = 0 ; ite < max_ites ; ite++ ){
|
||||
// 4.2: normalize vector x
|
||||
// x = x / |x|
|
||||
double nrm2_x;
|
||||
// TODO: cublasStat = hipblasDnrm2_v2(cublasH,
|
||||
cublasStat = cublasDnrm2_v2(cublasH,
|
||||
n,
|
||||
d_x,
|
||||
1, // incx,
|
||||
&nrm2_x /* host pointer */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
double one_over_nrm2_x = 1.0 / nrm2_x;
|
||||
// TODO: cublasStat = hipblasDscal_v2( cublasH,
|
||||
cublasStat = cublasDscal_v2( cublasH,
|
||||
n,
|
||||
&one_over_nrm2_x, /* host pointer */
|
||||
d_x,
|
||||
1 // incx
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
|
||||
// 4.3: y = A*x
|
||||
// TODO: hipsparseStat = cusparseDcsrmv_mp(cusparseH,
|
||||
// CHECK: HIPSPARSE_OPERATION_NON_TRANSPOSE
|
||||
cusparseStat = cusparseDcsrmv_mp(cusparseH,
|
||||
CUSPARSE_OPERATION_NON_TRANSPOSE,
|
||||
n,
|
||||
n,
|
||||
nnzA,
|
||||
&h_one,
|
||||
descrA,
|
||||
d_csrValA,
|
||||
d_csrRowPtrA,
|
||||
d_csrColIndA,
|
||||
d_x,
|
||||
&h_zero,
|
||||
d_y);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == cusparseStat);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == cusparseStat);
|
||||
|
||||
// 4.4: lambda = y**T*x
|
||||
// TODO: cublasStat = hipblasDdot_v2 ( cublasH,
|
||||
cublasStat = cublasDdot_v2 ( cublasH,
|
||||
n,
|
||||
d_x,
|
||||
1, // incx,
|
||||
d_y,
|
||||
1, // incy,
|
||||
&lambda_next /* host pointer */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
|
||||
double lambda_err = fabs( lambda_next - lambda_exact[0] );
|
||||
printf("ite %d: lambda = %f, error = %E\n", ite, lambda_next, lambda_err );
|
||||
|
||||
// 4.5: check if converges
|
||||
if ( (ite > 0) &&
|
||||
fabs( lambda - lambda_next ) < tol
|
||||
){
|
||||
break; // converges
|
||||
}
|
||||
|
||||
/*
|
||||
* 4.6: x := y
|
||||
* lambda = lambda_next
|
||||
*
|
||||
* so new approximation is (lambda, x), x is not normalized.
|
||||
*/
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_x, d_y, sizeof(double) * n , hipMemcpyDeviceToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_x, d_y, sizeof(double) * n , cudaMemcpyDeviceToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
lambda = lambda_next;
|
||||
}
|
||||
// step 5: report eigen-pair
|
||||
// CHECK: cudaStat1 = hipMemcpy(x, d_x, sizeof(double) * n, hipMemcpyDeviceToHost);
|
||||
cudaStat1 = cudaMemcpy(x, d_x, sizeof(double) * n, cudaMemcpyDeviceToHost);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
printf("largest eigenvalue is %E\n", lambda );
|
||||
printf("eigenvector = (matlab base-1)\n");
|
||||
printMatrix(n, 1, x, n, "V0");
|
||||
printf("=====\n");
|
||||
|
||||
// free resources
|
||||
// CHECK: if (d_csrRowPtrA ) hipFree(d_csrRowPtrA);
|
||||
if (d_csrRowPtrA ) cudaFree(d_csrRowPtrA);
|
||||
// CHECK: if (d_csrColIndA ) hipFree(d_csrColIndA);
|
||||
if (d_csrColIndA ) cudaFree(d_csrColIndA);
|
||||
// CHECK: if (d_csrValA ) hipFree(d_csrValA);
|
||||
if (d_csrValA ) cudaFree(d_csrValA);
|
||||
// CHECK: if (d_x ) hipFree(d_x);
|
||||
if (d_x ) cudaFree(d_x);
|
||||
// CHeCK: if (d_y ) hipFree(d_y);
|
||||
if (d_y ) cudaFree(d_y);
|
||||
// CHECK: if (cublasH ) hipblasDestroy(cublasH);
|
||||
if (cublasH ) cublasDestroy(cublasH);
|
||||
// CHECK: if (cusparseH ) hipsparseDestroy(cusparseH);
|
||||
if (cusparseH ) cusparseDestroy(cusparseH);
|
||||
// CHECK: if (stream ) hipStreamDestroy(stream);
|
||||
if (stream ) cudaStreamDestroy(stream);
|
||||
// CHECK: if (descrA ) hipsparseDestroyMatDescr(descrA);
|
||||
if (descrA ) cusparseDestroyMatDescr(descrA);
|
||||
// CHECK: hipDeviceReset();
|
||||
cudaDeviceReset();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,229 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args "--skip-excluded-preprocessor-conditional-blocks" %clang_args
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include "hipsparse.h"
|
||||
#include "cusparse.h"
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
// CHECK: hipsparseHandle_t handle = NULL;
|
||||
cusparseHandle_t handle = NULL;
|
||||
// CHECK: hipStream_t stream = NULL;
|
||||
cudaStream_t stream = NULL;
|
||||
// CHECK: hipsparseStatus_t status = HIPSPARSE_STATUS_SUCCESS;
|
||||
cusparseStatus_t status = CUSPARSE_STATUS_SUCCESS;
|
||||
// CHECK: hipError_t cudaStat1 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat2 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat3 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat4 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat5 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat6 = hipSuccess;
|
||||
cudaError_t cudaStat1 = cudaSuccess;
|
||||
cudaError_t cudaStat2 = cudaSuccess;
|
||||
cudaError_t cudaStat3 = cudaSuccess;
|
||||
cudaError_t cudaStat4 = cudaSuccess;
|
||||
cudaError_t cudaStat5 = cudaSuccess;
|
||||
cudaError_t cudaStat6 = cudaSuccess;
|
||||
|
||||
/*
|
||||
* A is a 3x3 sparse matrix
|
||||
* | 1 2 0 |
|
||||
* A = | 0 5 0 |
|
||||
* | 0 8 0 |
|
||||
*/
|
||||
const int m = 3;
|
||||
const int n = 3;
|
||||
const int nnz = 4;
|
||||
|
||||
#if 0
|
||||
/* index starts at 0 */
|
||||
int h_cooRows[nnz] = { 2, 1, 0, 0 };
|
||||
int h_cooCols[nnz] = { 1, 1, 0, 1 };
|
||||
#else
|
||||
/* index starts at -2 */
|
||||
int h_cooRows[nnz] = { 0, -1, -2, -2 };
|
||||
int h_cooCols[nnz] = { -1, -1, -2, -1 };
|
||||
#endif
|
||||
double h_cooVals[nnz] = { 8.0, 5.0, 1.0, 2.0 };
|
||||
int h_P[nnz];
|
||||
|
||||
int *d_cooRows = NULL;
|
||||
int *d_cooCols = NULL;
|
||||
int *d_P = NULL;
|
||||
double *d_cooVals = NULL;
|
||||
double *d_cooVals_sorted = NULL;
|
||||
size_t pBufferSizeInBytes = 0;
|
||||
void *pBuffer = NULL;
|
||||
|
||||
printf("m = %d, n = %d, nnz=%d \n", m, n, nnz);
|
||||
|
||||
/* step 1: create cusparse handle, bind a stream */
|
||||
// CHECK: cudaStat1 = hipStreamCreateWithFlags(&stream, hipStreamNonBlocking);
|
||||
cudaStat1 = cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: status = hipsparseCreate(&handle);
|
||||
status = cusparseCreate(&handle);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: status = hipsparseSetStream(handle, stream);
|
||||
status = cusparseSetStream(handle, stream);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
/* step 2: allocate buffer */
|
||||
// TODO: status = hipsparseXcoosort_bufferSizeExt(
|
||||
status = cusparseXcoosort_bufferSizeExt(
|
||||
handle,
|
||||
m,
|
||||
n,
|
||||
nnz,
|
||||
d_cooRows,
|
||||
d_cooCols,
|
||||
&pBufferSizeInBytes
|
||||
);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
printf("pBufferSizeInBytes = %lld bytes \n", (long long)pBufferSizeInBytes);
|
||||
|
||||
// CHECK: cudaStat1 = hipMalloc(&d_cooRows, sizeof(int)*nnz);
|
||||
cudaStat1 = cudaMalloc(&d_cooRows, sizeof(int)*nnz);
|
||||
// CHECK: cudaStat2 = hipMalloc(&d_cooCols, sizeof(int)*nnz);
|
||||
cudaStat2 = cudaMalloc(&d_cooCols, sizeof(int)*nnz);
|
||||
// CHECK: cudaStat3 = hipMalloc(&d_P, sizeof(int)*nnz);
|
||||
cudaStat3 = cudaMalloc(&d_P, sizeof(int)*nnz);
|
||||
// CHECK: cudaStat4 = hipMalloc(&d_cooVals, sizeof(double)*nnz);
|
||||
cudaStat4 = cudaMalloc(&d_cooVals, sizeof(double)*nnz);
|
||||
// CHECK: cudaStat5 = hipMalloc(&d_cooVals_sorted, sizeof(double)*nnz);
|
||||
cudaStat5 = cudaMalloc(&d_cooVals_sorted, sizeof(double)*nnz);
|
||||
// CHECK: cudaStat6 = hipMalloc(&pBuffer, sizeof(char)* pBufferSizeInBytes);
|
||||
cudaStat6 = cudaMalloc(&pBuffer, sizeof(char)* pBufferSizeInBytes);
|
||||
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
// CHECK: assert(hipSuccess == cudaStat2);
|
||||
// CHECK: assert(hipSuccess == cudaStat3);
|
||||
// CHECK: assert(hipSuccess == cudaStat4);
|
||||
// CHECK: assert(hipSuccess == cudaStat5);
|
||||
// CHECK: assert(hipSuccess == cudaStat6);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat2);
|
||||
assert(cudaSuccess == cudaStat3);
|
||||
assert(cudaSuccess == cudaStat4);
|
||||
assert(cudaSuccess == cudaStat5);
|
||||
assert(cudaSuccess == cudaStat6);
|
||||
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_cooRows, h_cooRows, sizeof(int)*nnz, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_cooRows, h_cooRows, sizeof(int)*nnz, cudaMemcpyHostToDevice);
|
||||
// CHECK: cudaStat2 = hipMemcpy(d_cooCols, h_cooCols, sizeof(int)*nnz, hipMemcpyHostToDevice);
|
||||
cudaStat2 = cudaMemcpy(d_cooCols, h_cooCols, sizeof(int)*nnz, cudaMemcpyHostToDevice);
|
||||
// CHECK: cudaStat3 = hipMemcpy(d_cooVals, h_cooVals, sizeof(double)*nnz, hipMemcpyHostToDevice);
|
||||
cudaStat3 = cudaMemcpy(d_cooVals, h_cooVals, sizeof(double)*nnz, cudaMemcpyHostToDevice);
|
||||
// CHECK: cudaStat4 = hipDeviceSynchronize();
|
||||
cudaStat4 = cudaDeviceSynchronize();
|
||||
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
// CHECK: assert(hipSuccess == cudaStat2);
|
||||
// CHECK: assert(hipSuccess == cudaStat3);
|
||||
// CHECK: assert(hipSuccess == cudaStat4);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat2);
|
||||
assert(cudaSuccess == cudaStat3);
|
||||
assert(cudaSuccess == cudaStat4);
|
||||
|
||||
/* step 3: setup permutation vector P to identity */
|
||||
// TODO: status = hipsparseCreateIdentityPermutation(
|
||||
status = cusparseCreateIdentityPermutation(
|
||||
handle,
|
||||
nnz,
|
||||
d_P);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
/* step 4: sort COO format by Row */
|
||||
// TODO: status = hipsparseXcoosortByRow(
|
||||
status = cusparseXcoosortByRow(
|
||||
handle,
|
||||
m,
|
||||
n,
|
||||
nnz,
|
||||
d_cooRows,
|
||||
d_cooCols,
|
||||
d_P,
|
||||
pBuffer
|
||||
);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
/* step 5: gather sorted cooVals */
|
||||
// CHECK: status = hipsparseDgthr(
|
||||
// CHECK: HIPSPARSE_INDEX_BASE_ZERO
|
||||
status = cusparseDgthr(
|
||||
handle,
|
||||
nnz,
|
||||
d_cooVals,
|
||||
d_cooVals_sorted,
|
||||
d_P,
|
||||
CUSPARSE_INDEX_BASE_ZERO
|
||||
);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
/* wait until the computation is done */
|
||||
// CHECK: cudaStat1 = hipDeviceSynchronize();
|
||||
cudaStat1 = cudaDeviceSynchronize();
|
||||
// CHECK: cudaStat2 = hipMemcpy(h_cooRows, d_cooRows, sizeof(int)*nnz, hipMemcpyDeviceToHost);
|
||||
cudaStat2 = cudaMemcpy(h_cooRows, d_cooRows, sizeof(int)*nnz, cudaMemcpyDeviceToHost);
|
||||
// CHECK: cudaStat3 = hipMemcpy(h_cooCols, d_cooCols, sizeof(int)*nnz, hipMemcpyDeviceToHost);
|
||||
cudaStat3 = cudaMemcpy(h_cooCols, d_cooCols, sizeof(int)*nnz, cudaMemcpyDeviceToHost);
|
||||
// CHECK: cudaStat4 = hipMemcpy(h_P, d_P, sizeof(int)*nnz, hipMemcpyDeviceToHost);
|
||||
cudaStat4 = cudaMemcpy(h_P, d_P, sizeof(int)*nnz, cudaMemcpyDeviceToHost);
|
||||
// CHECK: cudaStat5 = hipMemcpy(h_cooVals, d_cooVals_sorted, sizeof(double)*nnz, hipMemcpyDeviceToHost);
|
||||
cudaStat5 = cudaMemcpy(h_cooVals, d_cooVals_sorted, sizeof(double)*nnz, cudaMemcpyDeviceToHost);
|
||||
// CHECK: cudaStat6 = hipDeviceSynchronize();
|
||||
cudaStat6 = cudaDeviceSynchronize();
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
// CHECK: assert(hipSuccess == cudaStat2);
|
||||
// CHECK: assert(hipSuccess == cudaStat3);
|
||||
// CHECK: assert(hipSuccess == cudaStat4);
|
||||
// CHECK: assert(hipSuccess == cudaStat5);
|
||||
// CHECK: assert(hipSuccess == cudaStat6);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat2);
|
||||
assert(cudaSuccess == cudaStat3);
|
||||
assert(cudaSuccess == cudaStat4);
|
||||
assert(cudaSuccess == cudaStat5);
|
||||
assert(cudaSuccess == cudaStat6);
|
||||
|
||||
printf("sorted coo: \n");
|
||||
for (int j = 0; j < nnz; j++) {
|
||||
printf("(%d, %d, %f) \n", h_cooRows[j], h_cooCols[j], h_cooVals[j]);
|
||||
}
|
||||
|
||||
for (int j = 0; j < nnz; j++) {
|
||||
printf("P[%d] = %d \n", j, h_P[j]);
|
||||
}
|
||||
|
||||
/* free resources */
|
||||
// CHECK: if (d_cooRows) hipFree(d_cooRows);
|
||||
if (d_cooRows) cudaFree(d_cooRows);
|
||||
// CHECK: if (d_cooCols) hipFree(d_cooCols);
|
||||
if (d_cooCols) cudaFree(d_cooCols);
|
||||
// CHECK: if (d_P) hipFree(d_P);
|
||||
if (d_P) cudaFree(d_P);
|
||||
// CHECK: if (d_cooVals) hipFree(d_cooVals);
|
||||
if (d_cooVals) cudaFree(d_cooVals);
|
||||
// CHECK: if (d_cooVals_sorted) hipFree(d_cooVals_sorted);
|
||||
if (d_cooVals_sorted) cudaFree(d_cooVals_sorted);
|
||||
// CHECK: if (pBuffer) hipFree(pBuffer);
|
||||
if (pBuffer) cudaFree(pBuffer);
|
||||
// if (handle) hipsparseDestroy(handle);
|
||||
if (handle) cusparseDestroy(handle);
|
||||
// CHECK: if (stream) hipStreamDestroy(stream);
|
||||
if (stream) cudaStreamDestroy(stream);
|
||||
// CHECK: hipDeviceReset();
|
||||
cudaDeviceReset();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,261 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include <hipsparse.h>
|
||||
#include <cusparse.h>
|
||||
|
||||
void printMatrix(int m, int n, const float*A, int lda, const char* name)
|
||||
{
|
||||
for (int row = 0; row < m; row++) {
|
||||
for (int col = 0; col < n; col++) {
|
||||
float Areg = A[row + col * lda];
|
||||
printf("%s(%d,%d) = %f\n", name, row + 1, col + 1, Areg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void printCsr(
|
||||
int m,
|
||||
int n,
|
||||
int nnz,
|
||||
// CHECK: const hipsparseMatDescr_t descrA,
|
||||
const cusparseMatDescr_t descrA,
|
||||
const float *csrValA,
|
||||
const int *csrRowPtrA,
|
||||
const int *csrColIndA,
|
||||
const char* name)
|
||||
{
|
||||
// CHECK: const int base = (hipsparseGetMatIndexBase(descrA) != HIPSPARSE_INDEX_BASE_ONE) ? 0 : 1;
|
||||
const int base = (cusparseGetMatIndexBase(descrA) != CUSPARSE_INDEX_BASE_ONE) ? 0 : 1;
|
||||
|
||||
printf("matrix %s is %d-by-%d, nnz=%d, base=%d\n", name, m, n, nnz, base);
|
||||
for (int row = 0; row < m; row++) {
|
||||
const int start = csrRowPtrA[row] - base;
|
||||
const int end = csrRowPtrA[row + 1] - base;
|
||||
for (int colidx = start; colidx < end; colidx++) {
|
||||
const int col = csrColIndA[colidx] - base;
|
||||
const float Areg = csrValA[colidx];
|
||||
printf("%s(%d,%d) = %f\n", name, row + 1, col + 1, Areg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
// CHECK: hipsparseHandle_t handle = NULL;
|
||||
cusparseHandle_t handle = NULL;
|
||||
// CHECK: hipStream_t stream = NULL;
|
||||
cudaStream_t stream = NULL;
|
||||
// CHECK: hipsparseMatDescr_t descrC = NULL;
|
||||
cusparseMatDescr_t descrC = NULL;
|
||||
// CHECK: hipsparseStatus_t status = HIPSPARSE_STATUS_SUCCESS;
|
||||
cusparseStatus_t status = CUSPARSE_STATUS_SUCCESS;
|
||||
// CHECK: hipError_t cudaStat1 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat2 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat3 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat4 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat5 = hipSuccess;
|
||||
cudaError_t cudaStat1 = cudaSuccess;
|
||||
cudaError_t cudaStat2 = cudaSuccess;
|
||||
cudaError_t cudaStat3 = cudaSuccess;
|
||||
cudaError_t cudaStat4 = cudaSuccess;
|
||||
cudaError_t cudaStat5 = cudaSuccess;
|
||||
const int m = 4;
|
||||
const int n = 4;
|
||||
const int lda = m;
|
||||
/*
|
||||
* | 1 0 2 -3 |
|
||||
* | 0 4 0 0 |
|
||||
* A = | 5 0 6 7 |
|
||||
* | 0 8 0 9 |
|
||||
*
|
||||
*/
|
||||
const float A[lda*n] = { 1, 0, 5, 0, 0, 4, 0, 8, 2, 0, 6, 0, -3, 0, 7, 9 };
|
||||
int* csrRowPtrC = NULL;
|
||||
int* csrColIndC = NULL;
|
||||
float* csrValC = NULL;
|
||||
|
||||
float *d_A = NULL;
|
||||
int *d_csrRowPtrC = NULL;
|
||||
int *d_csrColIndC = NULL;
|
||||
float *d_csrValC = NULL;
|
||||
|
||||
size_t lworkInBytes = 0;
|
||||
char *d_work = NULL;
|
||||
|
||||
int nnzC = 0;
|
||||
|
||||
float threshold = 4.1; /* remove Aij <= 4.1 */
|
||||
// float threshold = 0; /* remove zeros */
|
||||
|
||||
printf("example of pruneDense2csr \n");
|
||||
|
||||
printf("prune |A(i,j)| <= threshold \n");
|
||||
printf("threshold = %E \n", threshold);
|
||||
|
||||
printMatrix(m, n, A, lda, "A");
|
||||
|
||||
/* step 1: create cusparse handle, bind a stream */
|
||||
// CHECK: cudaStat1 = hipStreamCreateWithFlags(&stream, hipStreamNonBlocking);
|
||||
cudaStat1 = cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: status = hipsparseCreate(&handle);
|
||||
status = cusparseCreate(&handle);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: status = hipsparseSetStream(handle, stream);
|
||||
status = cusparseSetStream(handle, stream);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
/* step 2: configuration of matrix C */
|
||||
// CHECK: status = hipsparseCreateMatDescr(&descrC);
|
||||
status = cusparseCreateMatDescr(&descrC);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: hipsparseSetMatIndexBase(descrC, HIPSPARSE_INDEX_BASE_ZERO);
|
||||
cusparseSetMatIndexBase(descrC, CUSPARSE_INDEX_BASE_ZERO);
|
||||
// CHECK: hipsparseSetMatType(descrC, HIPSPARSE_MATRIX_TYPE_GENERAL);
|
||||
cusparseSetMatType(descrC, CUSPARSE_MATRIX_TYPE_GENERAL);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_A, sizeof(float)*lda*n);
|
||||
cudaStat1 = cudaMalloc((void**)&d_A, sizeof(float)*lda*n);
|
||||
// CHECK: cudaStat2 = hipMalloc((void**)&d_csrRowPtrC, sizeof(int)*(m + 1));
|
||||
cudaStat2 = cudaMalloc((void**)&d_csrRowPtrC, sizeof(int)*(m + 1));
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
// CHECK: assert(hipSuccess == cudaStat2);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat2);
|
||||
|
||||
/* step 3: query workspace */
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_A, A, sizeof(float)*lda*n, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_A, A, sizeof(float)*lda*n, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// TODO: status = hipsparseSpruneDense2csr_bufferSizeExt(
|
||||
status = cusparseSpruneDense2csr_bufferSizeExt(
|
||||
handle,
|
||||
m,
|
||||
n,
|
||||
d_A,
|
||||
lda,
|
||||
&threshold,
|
||||
descrC,
|
||||
d_csrValC,
|
||||
d_csrRowPtrC,
|
||||
d_csrColIndC,
|
||||
&lworkInBytes);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
printf("lworkInBytes (prune) = %lld \n", (long long)lworkInBytes);
|
||||
// CHECK: if (NULL != d_work) { hipFree(d_work); }
|
||||
if (NULL != d_work) { cudaFree(d_work); }
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_work, lworkInBytes);
|
||||
cudaStat1 = cudaMalloc((void**)&d_work, lworkInBytes);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 4: compute csrRowPtrC and nnzC */
|
||||
// TODO: status = hipsparseSpruneDense2csrNnz(
|
||||
status = cusparseSpruneDense2csrNnz(
|
||||
handle,
|
||||
m,
|
||||
n,
|
||||
d_A,
|
||||
lda,
|
||||
&threshold,
|
||||
descrC,
|
||||
d_csrRowPtrC,
|
||||
&nnzC, /* host */
|
||||
d_work);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: cudaStat1 = hipDeviceSynchronize();
|
||||
cudaStat1 = cudaDeviceSynchronize();
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
printf("nnzC = %d\n", nnzC);
|
||||
if (0 == nnzC) {
|
||||
printf("C is empty \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* step 5: compute csrColIndC and csrValC */
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrColIndC, sizeof(int) * nnzC);
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrColIndC, sizeof(int) * nnzC);
|
||||
// CHECK: cudaStat2 = hipMalloc((void**)&d_csrValC, sizeof(float) * nnzC);
|
||||
cudaStat2 = cudaMalloc((void**)&d_csrValC, sizeof(float) * nnzC);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
// CHECK: assert(hipSuccess == cudaStat2);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat2);
|
||||
// TODO: status = hipsparseSpruneDense2csr(
|
||||
status = cusparseSpruneDense2csr(
|
||||
handle,
|
||||
m,
|
||||
n,
|
||||
d_A,
|
||||
lda,
|
||||
&threshold,
|
||||
descrC,
|
||||
d_csrValC,
|
||||
d_csrRowPtrC,
|
||||
d_csrColIndC,
|
||||
d_work);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: cudaStat1 = hipDeviceSynchronize();
|
||||
cudaStat1 = cudaDeviceSynchronize();
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 6: output C */
|
||||
csrRowPtrC = (int*)malloc(sizeof(int)*(m + 1));
|
||||
csrColIndC = (int*)malloc(sizeof(int)*nnzC);
|
||||
csrValC = (float*)malloc(sizeof(float)*nnzC);
|
||||
assert(NULL != csrRowPtrC);
|
||||
assert(NULL != csrColIndC);
|
||||
assert(NULL != csrValC);
|
||||
// CHECK: cudaStat1 = hipMemcpy(csrRowPtrC, d_csrRowPtrC, sizeof(int)*(m + 1), hipMemcpyDeviceToHost);
|
||||
cudaStat1 = cudaMemcpy(csrRowPtrC, d_csrRowPtrC, sizeof(int)*(m + 1), cudaMemcpyDeviceToHost);
|
||||
// CHECK: cudaStat2 = hipMemcpy(csrColIndC, d_csrColIndC, sizeof(int)*nnzC, hipMemcpyDeviceToHost);
|
||||
cudaStat2 = cudaMemcpy(csrColIndC, d_csrColIndC, sizeof(int)*nnzC, cudaMemcpyDeviceToHost);
|
||||
// CHECK: cudaStat3 = hipMemcpy(csrValC, d_csrValC, sizeof(float)*nnzC, hipMemcpyDeviceToHost);
|
||||
cudaStat3 = cudaMemcpy(csrValC, d_csrValC, sizeof(float)*nnzC, cudaMemcpyDeviceToHost);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
// CHECK: assert(hipSuccess == cudaStat2);
|
||||
// CHECK: assert(hipSuccess == cudaStat3);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat2);
|
||||
assert(cudaSuccess == cudaStat3);
|
||||
|
||||
printCsr(m, n, nnzC, descrC, csrValC, csrRowPtrC, csrColIndC, "C");
|
||||
|
||||
/* free resources */
|
||||
// CHECK: if (d_A) hipFree(d_A);
|
||||
if (d_A) cudaFree(d_A);
|
||||
// CHECK: if (d_csrRowPtrC) hipFree(d_csrRowPtrC);
|
||||
if (d_csrRowPtrC) cudaFree(d_csrRowPtrC);
|
||||
// CHECK: if (d_csrColIndC) hipFree(d_csrColIndC);
|
||||
if (d_csrColIndC) cudaFree(d_csrColIndC);
|
||||
// CHECK: if (d_csrValC) hipFree(d_csrValC);
|
||||
if (d_csrValC) cudaFree(d_csrValC);
|
||||
|
||||
if (csrRowPtrC) free(csrRowPtrC);
|
||||
if (csrColIndC) free(csrColIndC);
|
||||
if (csrValC) free(csrValC);
|
||||
// CHECK: if (handle) hipsparseDestroy(handle);
|
||||
if (handle) cusparseDestroy(handle);
|
||||
// CHECK: if (stream) hipStreamDestroy(stream);
|
||||
if (stream) cudaStreamDestroy(stream);
|
||||
// CHECK: if (descrC) hipsparseDestroyMatDescr(descrC);
|
||||
if (descrC) cusparseDestroyMatDescr(descrC);
|
||||
// CHECK: hipDeviceReset();
|
||||
cudaDeviceReset();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,288 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include <hipsparse.h>
|
||||
#include <cusparse.h>
|
||||
|
||||
void printCsr(
|
||||
int m,
|
||||
int n,
|
||||
int nnz,
|
||||
// CHECK: const hipsparseMatDescr_t descrA,
|
||||
const cusparseMatDescr_t descrA,
|
||||
const float *csrValA,
|
||||
const int *csrRowPtrA,
|
||||
const int *csrColIndA,
|
||||
const char* name)
|
||||
{
|
||||
// CHECK: const int base = (hipsparseGetMatIndexBase(descrA) != HIPSPARSE_INDEX_BASE_ONE) ? 0 : 1;
|
||||
const int base = (cusparseGetMatIndexBase(descrA) != CUSPARSE_INDEX_BASE_ONE) ? 0 : 1;
|
||||
|
||||
printf("matrix %s is %d-by-%d, nnz=%d, base=%d, output base-1\n", name, m, n, nnz, base);
|
||||
for (int row = 0; row < m; row++) {
|
||||
const int start = csrRowPtrA[row] - base;
|
||||
const int end = csrRowPtrA[row + 1] - base;
|
||||
for (int colidx = start; colidx < end; colidx++) {
|
||||
const int col = csrColIndA[colidx] - base;
|
||||
const float Areg = csrValA[colidx];
|
||||
printf("%s(%d,%d) = %f\n", name, row + 1, col + 1, Areg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
// CHECK: hipsparseHandle_t handle = NULL;
|
||||
cusparseHandle_t handle = NULL;
|
||||
// CHECK: hipStream_t stream = NULL;
|
||||
cudaStream_t stream = NULL;
|
||||
// CHECK: hipsparseMatDescr_t descrA = NULL;
|
||||
cusparseMatDescr_t descrA = NULL;
|
||||
// CHECK: hipsparseMatDescr_t descrC = NULL;
|
||||
cusparseMatDescr_t descrC = NULL;
|
||||
// CHECK: hipsparseStatus_t status = HIPSPARSE_STATUS_SUCCESS;
|
||||
cusparseStatus_t status = CUSPARSE_STATUS_SUCCESS;
|
||||
// CHECK: hipError_t cudaStat1 = hipSuccess;
|
||||
cudaError_t cudaStat1 = cudaSuccess;
|
||||
const int m = 4;
|
||||
const int n = 4;
|
||||
const int nnzA = 9;
|
||||
/*
|
||||
* | 1 0 2 -3 |
|
||||
* | 0 4 0 0 |
|
||||
* A = | 5 0 6 7 |
|
||||
* | 0 8 0 9 |
|
||||
*
|
||||
*/
|
||||
|
||||
const int csrRowPtrA[m + 1] = { 1, 4, 5, 8, 10 };
|
||||
const int csrColIndA[nnzA] = { 1, 3, 4, 2, 1, 3, 4, 2, 4 };
|
||||
const float csrValA[nnzA] = { 1, 2, -3, 4, 5, 6, 7, 8, 9 };
|
||||
|
||||
int* csrRowPtrC = NULL;
|
||||
int* csrColIndC = NULL;
|
||||
float* csrValC = NULL;
|
||||
|
||||
int *d_csrRowPtrA = NULL;
|
||||
int *d_csrColIndA = NULL;
|
||||
float *d_csrValA = NULL;
|
||||
|
||||
int *d_csrRowPtrC = NULL;
|
||||
int *d_csrColIndC = NULL;
|
||||
float *d_csrValC = NULL;
|
||||
|
||||
size_t lworkInBytes = 0;
|
||||
char *d_work = NULL;
|
||||
|
||||
int nnzC = 0;
|
||||
|
||||
float threshold = 4.1; /* remove Aij <= 4.1 */
|
||||
// float threshold = 0; /* remove zeros */
|
||||
|
||||
printf("example of pruneCsr2csr \n");
|
||||
|
||||
printf("prune |A(i,j)| <= threshold \n");
|
||||
printf("threshold = %E \n", threshold);
|
||||
|
||||
/* step 1: create cusparse handle, bind a stream */
|
||||
// CHECK: cudaStat1 = hipStreamCreateWithFlags(&stream, hipStreamNonBlocking);
|
||||
cudaStat1 = cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: status = hipsparseCreate(&handle);
|
||||
status = cusparseCreate(&handle);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: status = hipsparseSetStream(handle, stream);
|
||||
status = cusparseSetStream(handle, stream);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
/* step 2: configuration of matrix A and C */
|
||||
// CHECK: status = hipsparseCreateMatDescr(&descrA);
|
||||
status = cusparseCreateMatDescr(&descrA);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
/* A is base-1*/
|
||||
// CHECK: hipsparseSetMatIndexBase(descrA, HIPSPARSE_INDEX_BASE_ONE);
|
||||
cusparseSetMatIndexBase(descrA, CUSPARSE_INDEX_BASE_ONE);
|
||||
// CHECK: hipsparseSetMatType(descrA, HIPSPARSE_MATRIX_TYPE_GENERAL);
|
||||
cusparseSetMatType(descrA, CUSPARSE_MATRIX_TYPE_GENERAL);
|
||||
// CHECK: status = hipsparseCreateMatDescr(&descrC);
|
||||
status = cusparseCreateMatDescr(&descrC);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
/* C is base-0 */
|
||||
// CHECK: hipsparseSetMatIndexBase(descrC, HIPSPARSE_INDEX_BASE_ZERO);
|
||||
cusparseSetMatIndexBase(descrC, CUSPARSE_INDEX_BASE_ZERO);
|
||||
// CHECK: hipsparseSetMatType(descrC, HIPSPARSE_MATRIX_TYPE_GENERAL);
|
||||
cusparseSetMatType(descrC, CUSPARSE_MATRIX_TYPE_GENERAL);
|
||||
|
||||
printCsr(m, n, nnzA, descrA, csrValA, csrRowPtrA, csrColIndA, "A");
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrRowPtrA, sizeof(int)*(m + 1));
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrRowPtrA, sizeof(int)*(m + 1));
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrColIndA, sizeof(int)*nnzA);
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrColIndA, sizeof(int)*nnzA);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrValA, sizeof(float)*nnzA);
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrValA, sizeof(float)*nnzA);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrRowPtrC, sizeof(int)*(m + 1));
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrRowPtrC, sizeof(int)*(m + 1));
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_csrRowPtrA, csrRowPtrA, sizeof(int)*(m + 1), hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_csrRowPtrA, csrRowPtrA, sizeof(int)*(m + 1), cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_csrColIndA, csrColIndA, sizeof(int)*nnzA, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_csrColIndA, csrColIndA, sizeof(int)*nnzA, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_csrValA, csrValA, sizeof(float)*nnzA, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_csrValA, csrValA, sizeof(float)*nnzA, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 3: query workspace */
|
||||
// TODO: status = hipsparseSpruneCsr2csr_bufferSizeExt(
|
||||
status = cusparseSpruneCsr2csr_bufferSizeExt(
|
||||
handle,
|
||||
m,
|
||||
n,
|
||||
nnzA,
|
||||
descrA,
|
||||
d_csrValA,
|
||||
d_csrRowPtrA,
|
||||
d_csrColIndA,
|
||||
&threshold,
|
||||
descrC,
|
||||
d_csrValC,
|
||||
d_csrRowPtrC,
|
||||
d_csrColIndC,
|
||||
&lworkInBytes);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
printf("lworkInBytes (prune) = %lld \n", (long long)lworkInBytes);
|
||||
// CHECK: if (NULL != d_work) { hipFree(d_work); }
|
||||
if (NULL != d_work) { cudaFree(d_work); }
|
||||
// cudaStat1 = hipMalloc((void**)&d_work, lworkInBytes);
|
||||
cudaStat1 = cudaMalloc((void**)&d_work, lworkInBytes);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 4: compute csrRowPtrC and nnzC */
|
||||
// TODO: status = hipsparseSpruneCsr2csrNnz(
|
||||
status = cusparseSpruneCsr2csrNnz(
|
||||
handle,
|
||||
m,
|
||||
n,
|
||||
nnzA,
|
||||
descrA,
|
||||
d_csrValA,
|
||||
d_csrRowPtrA,
|
||||
d_csrColIndA,
|
||||
&threshold,
|
||||
descrC,
|
||||
d_csrRowPtrC,
|
||||
&nnzC, /* host */
|
||||
d_work);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: cudaStat1 = hipDeviceSynchronize();
|
||||
cudaStat1 = cudaDeviceSynchronize();
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
printf("nnzC = %d\n", nnzC);
|
||||
if (0 == nnzC) {
|
||||
printf("C is empty \n");
|
||||
return 0;
|
||||
}
|
||||
/* step 5: compute csrColIndC and csrValC */
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrColIndC, sizeof(int) * nnzC);
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrColIndC, sizeof(int) * nnzC);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrValC, sizeof(float) * nnzC);
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrValC, sizeof(float) * nnzC);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// TODO: status = hipsparseSpruneCsr2csr(
|
||||
status = cusparseSpruneCsr2csr(
|
||||
handle,
|
||||
m,
|
||||
n,
|
||||
nnzA,
|
||||
descrA,
|
||||
d_csrValA,
|
||||
d_csrRowPtrA,
|
||||
d_csrColIndA,
|
||||
&threshold,
|
||||
descrC,
|
||||
d_csrValC,
|
||||
d_csrRowPtrC,
|
||||
d_csrColIndC,
|
||||
d_work);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: cudaStat1 = hipDeviceSynchronize();
|
||||
cudaStat1 = cudaDeviceSynchronize();
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 6: output C */
|
||||
csrRowPtrC = (int*)malloc(sizeof(int)*(m + 1));
|
||||
csrColIndC = (int*)malloc(sizeof(int)*nnzC);
|
||||
csrValC = (float*)malloc(sizeof(float)*nnzC);
|
||||
assert(NULL != csrRowPtrC);
|
||||
assert(NULL != csrColIndC);
|
||||
assert(NULL != csrValC);
|
||||
// CHECK: cudaStat1 = hipMemcpy(csrRowPtrC, d_csrRowPtrC, sizeof(int)*(m + 1), hipMemcpyDeviceToHost);
|
||||
cudaStat1 = cudaMemcpy(csrRowPtrC, d_csrRowPtrC, sizeof(int)*(m + 1), cudaMemcpyDeviceToHost);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(csrColIndC, d_csrColIndC, sizeof(int)*nnzC, hipMemcpyDeviceToHost);
|
||||
cudaStat1 = cudaMemcpy(csrColIndC, d_csrColIndC, sizeof(int)*nnzC, cudaMemcpyDeviceToHost);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(csrValC, d_csrValC, sizeof(float)*nnzC, hipMemcpyDeviceToHost);
|
||||
cudaStat1 = cudaMemcpy(csrValC, d_csrValC, sizeof(float)*nnzC, cudaMemcpyDeviceToHost);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
printCsr(m, n, nnzC, descrC, csrValC, csrRowPtrC, csrColIndC, "C");
|
||||
/* free resources */
|
||||
// CHECK: if (d_csrRowPtrA) hipFree(d_csrRowPtrA);
|
||||
if (d_csrRowPtrA) cudaFree(d_csrRowPtrA);
|
||||
// CHECK: if (d_csrColIndA) hipFree(d_csrColIndA);
|
||||
if (d_csrColIndA) cudaFree(d_csrColIndA);
|
||||
// CHECK: if (d_csrValA) hipFree(d_csrValA);
|
||||
if (d_csrValA) cudaFree(d_csrValA);
|
||||
// CHECK: if (d_csrRowPtrC) hipFree(d_csrRowPtrC);
|
||||
if (d_csrRowPtrC) cudaFree(d_csrRowPtrC);
|
||||
// CHECK: if (d_csrColIndC) hipFree(d_csrColIndC);
|
||||
if (d_csrColIndC) cudaFree(d_csrColIndC);
|
||||
// CHECK: if (d_csrValC) hipFree(d_csrValC);
|
||||
if (d_csrValC) cudaFree(d_csrValC);
|
||||
if (csrRowPtrC) free(csrRowPtrC);
|
||||
if (csrColIndC) free(csrColIndC);
|
||||
if (csrValC) free(csrValC);
|
||||
// CHECK: if (handle) hipsparseDestroy(handle);
|
||||
if (handle) cusparseDestroy(handle);
|
||||
// CHECK: if (stream) hipStreamDestroy(stream);
|
||||
if (stream) cudaStreamDestroy(stream);
|
||||
// CHECK: if (descrA) hipsparseDestroyMatDescr(descrA);
|
||||
if (descrA) cusparseDestroyMatDescr(descrA);
|
||||
// CHECK: if (descrC) hipsparseDestroyMatDescr(descrC);
|
||||
if (descrC) cusparseDestroyMatDescr(descrC);
|
||||
// CHECK: hipDeviceReset();
|
||||
cudaDeviceReset();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,269 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include <hipsparse.h>
|
||||
#include <cusparse.h>
|
||||
|
||||
void printMatrix(int m, int n, const float*A, int lda, const char* name)
|
||||
{
|
||||
for (int row = 0; row < m; row++) {
|
||||
for (int col = 0; col < n; col++) {
|
||||
float Areg = A[row + col * lda];
|
||||
printf("%s(%d,%d) = %f\n", name, row + 1, col + 1, Areg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void printCsr(
|
||||
int m,
|
||||
int n,
|
||||
int nnz,
|
||||
// CHECK: const hipsparseMatDescr_t descrA,
|
||||
const cusparseMatDescr_t descrA,
|
||||
const float *csrValA,
|
||||
const int *csrRowPtrA,
|
||||
const int *csrColIndA,
|
||||
const char* name)
|
||||
{
|
||||
// CHECK: const int base = (hipsparseGetMatIndexBase(descrA) != HIPSPARSE_INDEX_BASE_ONE) ? 0 : 1;
|
||||
const int base = (cusparseGetMatIndexBase(descrA) != CUSPARSE_INDEX_BASE_ONE) ? 0 : 1;
|
||||
|
||||
printf("matrix %s is %d-by-%d, nnz=%d, base=%d, output base-1\n", name, m, n, nnz, base);
|
||||
for (int row = 0; row < m; row++) {
|
||||
const int start = csrRowPtrA[row] - base;
|
||||
const int end = csrRowPtrA[row + 1] - base;
|
||||
for (int colidx = start; colidx < end; colidx++) {
|
||||
const int col = csrColIndA[colidx] - base;
|
||||
const float Areg = csrValA[colidx];
|
||||
printf("%s(%d,%d) = %f\n", name, row + 1, col + 1, Areg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
// CHECK: hipsparseHandle_t handle = NULL;
|
||||
cusparseHandle_t handle = NULL;
|
||||
// CHECK: hipStream_t stream = NULL;
|
||||
cudaStream_t stream = NULL;
|
||||
// CHECK: hipsparseMatDescr_t descrC = NULL;
|
||||
cusparseMatDescr_t descrC = NULL;
|
||||
pruneInfo_t info = NULL;
|
||||
// CHECK: hipsparseStatus_t status = HIPSPARSE_STATUS_SUCCESS;
|
||||
cusparseStatus_t status = CUSPARSE_STATUS_SUCCESS;
|
||||
// CHECK: hipError_t cudaStat1 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat2 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat3 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat4 = hipSuccess;
|
||||
// CHECK: hipError_t cudaStat5 = hipSuccess;
|
||||
cudaError_t cudaStat1 = cudaSuccess;
|
||||
cudaError_t cudaStat2 = cudaSuccess;
|
||||
cudaError_t cudaStat3 = cudaSuccess;
|
||||
cudaError_t cudaStat4 = cudaSuccess;
|
||||
cudaError_t cudaStat5 = cudaSuccess;
|
||||
const int m = 4;
|
||||
const int n = 4;
|
||||
const int lda = m;
|
||||
/*
|
||||
* | 1 0 2 -3 |
|
||||
* | 0 4 0 0 |
|
||||
* A = | 5 0 6 7 |
|
||||
* | 0 8 0 9 |
|
||||
*
|
||||
*/
|
||||
const float A[lda*n] = { 1, 0, 5, 0, 0, 4, 0, 8, 2, 0, 6, 0, -3, 0, 7, 9 };
|
||||
int* csrRowPtrC = NULL;
|
||||
int* csrColIndC = NULL;
|
||||
float* csrValC = NULL;
|
||||
|
||||
float *d_A = NULL;
|
||||
int *d_csrRowPtrC = NULL;
|
||||
int *d_csrColIndC = NULL;
|
||||
float *d_csrValC = NULL;
|
||||
|
||||
size_t lworkInBytes = 0;
|
||||
char *d_work = NULL;
|
||||
|
||||
int nnzC = 0;
|
||||
|
||||
float percentage = 50; /* 50% of nnz */
|
||||
|
||||
printf("example of pruneDense2csrByPercentage \n");
|
||||
|
||||
printf("prune out %.1f percentage of A \n", percentage);
|
||||
|
||||
printMatrix(m, n, A, lda, "A");
|
||||
|
||||
/* step 1: create cusparse handle, bind a stream */
|
||||
// CHECK: cudaStat1 = hipStreamCreateWithFlags(&stream, hipStreamNonBlocking);
|
||||
cudaStat1 = cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: status = hipsparseCreate(&handle);
|
||||
status = cusparseCreate(&handle);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: status = hipsparseSetStream(handle, stream);
|
||||
status = cusparseSetStream(handle, stream);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// TODO: status = hipsparseCreatePruneInfo(&info);
|
||||
status = cusparseCreatePruneInfo(&info);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
/* step 2: configuration of matrix C */
|
||||
// CHECK: status = hipsparseCreateMatDescr(&descrC);
|
||||
status = cusparseCreateMatDescr(&descrC);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: hipsparseSetMatIndexBase(descrC, HIPSPARSE_INDEX_BASE_ZERO);
|
||||
cusparseSetMatIndexBase(descrC, CUSPARSE_INDEX_BASE_ZERO);
|
||||
// CHECK: hipsparseSetMatType(descrC, HIPSPARSE_MATRIX_TYPE_GENERAL);
|
||||
cusparseSetMatType(descrC, CUSPARSE_MATRIX_TYPE_GENERAL);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_A, sizeof(float)*lda*n);
|
||||
cudaStat1 = cudaMalloc((void**)&d_A, sizeof(float)*lda*n);
|
||||
// CHECK: cudaStat2 = hipMalloc((void**)&d_csrRowPtrC, sizeof(int)*(m + 1));
|
||||
cudaStat2 = cudaMalloc((void**)&d_csrRowPtrC, sizeof(int)*(m + 1));
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
// CHECK: assert(hipSuccess == cudaStat2);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat2);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_A, A, sizeof(float)*lda*n, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_A, A, sizeof(float)*lda*n, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
/* step 3: query workspace */
|
||||
// TODO: status = hipsparseSpruneDense2csrByPercentage_bufferSizeExt(
|
||||
status = cusparseSpruneDense2csrByPercentage_bufferSizeExt(
|
||||
handle,
|
||||
m,
|
||||
n,
|
||||
d_A,
|
||||
lda,
|
||||
percentage,
|
||||
descrC,
|
||||
d_csrValC,
|
||||
d_csrRowPtrC,
|
||||
d_csrColIndC,
|
||||
info,
|
||||
&lworkInBytes);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
printf("lworkInBytes = %lld \n", (long long)lworkInBytes);
|
||||
// CHECK: if (NULL != d_work) { hipFree(d_work); }
|
||||
if (NULL != d_work) { cudaFree(d_work); }
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_work, lworkInBytes);
|
||||
cudaStat1 = cudaMalloc((void**)&d_work, lworkInBytes);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 4: compute csrRowPtrC and nnzC */
|
||||
// TODO: status = hipsparseSpruneDense2csrNnzByPercentage(
|
||||
status = cusparseSpruneDense2csrNnzByPercentage(
|
||||
handle,
|
||||
m,
|
||||
n,
|
||||
d_A,
|
||||
lda,
|
||||
percentage,
|
||||
descrC,
|
||||
d_csrRowPtrC,
|
||||
&nnzC, /* host */
|
||||
info,
|
||||
d_work);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: cudaStat1 = hipDeviceSynchronize();
|
||||
cudaStat1 = cudaDeviceSynchronize();
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
printf("nnzC = %d\n", nnzC);
|
||||
if (0 == nnzC) {
|
||||
printf("C is empty \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* step 5: compute csrColIndC and csrValC */
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrColIndC, sizeof(int) * nnzC);
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrColIndC, sizeof(int) * nnzC);
|
||||
// CHECK: cudaStat2 = hipMalloc((void**)&d_csrValC, sizeof(float) * nnzC);
|
||||
cudaStat2 = cudaMalloc((void**)&d_csrValC, sizeof(float) * nnzC);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: assert(hipSuccess == cudaStat2);
|
||||
assert(cudaSuccess == cudaStat2);
|
||||
// TODO: status = hipsparseSpruneDense2csrByPercentage(
|
||||
status = cusparseSpruneDense2csrByPercentage(
|
||||
handle,
|
||||
m,
|
||||
n,
|
||||
d_A,
|
||||
lda,
|
||||
percentage,
|
||||
descrC,
|
||||
d_csrValC,
|
||||
d_csrRowPtrC,
|
||||
d_csrColIndC,
|
||||
info,
|
||||
d_work);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: cudaStat1 = hipDeviceSynchronize();
|
||||
cudaStat1 = cudaDeviceSynchronize();
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 7: output C */
|
||||
csrRowPtrC = (int*)malloc(sizeof(int)*(m + 1));
|
||||
csrColIndC = (int*)malloc(sizeof(int)*nnzC);
|
||||
csrValC = (float*)malloc(sizeof(float)*nnzC);
|
||||
assert(NULL != csrRowPtrC);
|
||||
assert(NULL != csrColIndC);
|
||||
assert(NULL != csrValC);
|
||||
// CHECK: cudaStat1 = hipMemcpy(csrRowPtrC, d_csrRowPtrC, sizeof(int)*(m + 1), hipMemcpyDeviceToHost);
|
||||
cudaStat1 = cudaMemcpy(csrRowPtrC, d_csrRowPtrC, sizeof(int)*(m + 1), cudaMemcpyDeviceToHost);
|
||||
// CHECK: cudaStat2 = hipMemcpy(csrColIndC, d_csrColIndC, sizeof(int)*nnzC, hipMemcpyDeviceToHost);
|
||||
cudaStat2 = cudaMemcpy(csrColIndC, d_csrColIndC, sizeof(int)*nnzC, cudaMemcpyDeviceToHost);
|
||||
// CHECK: cudaStat3 = hipMemcpy(csrValC, d_csrValC, sizeof(float)*nnzC, hipMemcpyDeviceToHost);
|
||||
cudaStat3 = cudaMemcpy(csrValC, d_csrValC, sizeof(float)*nnzC, cudaMemcpyDeviceToHost);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
// CHECK: assert(hipSuccess == cudaStat2);
|
||||
// CHECK: assert(hipSuccess == cudaStat3);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat2);
|
||||
assert(cudaSuccess == cudaStat3);
|
||||
|
||||
printCsr(m, n, nnzC, descrC, csrValC, csrRowPtrC, csrColIndC, "C");
|
||||
|
||||
/* free resources */
|
||||
// CHECK: if (d_A) hipFree(d_A);
|
||||
if (d_A) cudaFree(d_A);
|
||||
// CHECK: if (d_csrRowPtrC) hipFree(d_csrRowPtrC);
|
||||
if (d_csrRowPtrC) cudaFree(d_csrRowPtrC);
|
||||
// CHECK: if (d_csrColIndC) hipFree(d_csrColIndC);
|
||||
if (d_csrColIndC) cudaFree(d_csrColIndC);
|
||||
// CHECK: if (d_csrValC) hipFree(d_csrValC);
|
||||
if (d_csrValC) cudaFree(d_csrValC);
|
||||
|
||||
if (csrRowPtrC) free(csrRowPtrC);
|
||||
if (csrColIndC) free(csrColIndC);
|
||||
if (csrValC) free(csrValC);
|
||||
// CHECK: if (handle) hipsparseDestroy(handle);
|
||||
if (handle) cusparseDestroy(handle);
|
||||
// CHECK: if (stream) hipStreamDestroy(stream);
|
||||
if (stream) cudaStreamDestroy(stream);
|
||||
// CHECK: if (descrC) hipsparseDestroyMatDescr(descrC);
|
||||
if (descrC) cusparseDestroyMatDescr(descrC);
|
||||
// TODO: if (info) hipsparseDestroyPruneInfo(info);
|
||||
if (info) cusparseDestroyPruneInfo(info);
|
||||
// CHECK: hipDeviceReset();
|
||||
cudaDeviceReset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,302 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include <hipsparse.h>
|
||||
#include <cusparse.h>
|
||||
|
||||
void printCsr(
|
||||
int m,
|
||||
int n,
|
||||
int nnz,
|
||||
// CHECK: const hipsparseMatDescr_t descrA,
|
||||
const cusparseMatDescr_t descrA,
|
||||
const float *csrValA,
|
||||
const int *csrRowPtrA,
|
||||
const int *csrColIndA,
|
||||
const char* name)
|
||||
{
|
||||
// CHECK: const int base = (hipsparseGetMatIndexBase(descrA) != HIPSPARSE_INDEX_BASE_ONE) ? 0 : 1;
|
||||
const int base = (cusparseGetMatIndexBase(descrA) != CUSPARSE_INDEX_BASE_ONE) ? 0 : 1;
|
||||
|
||||
printf("matrix %s is %d-by-%d, nnz=%d, base=%d, output base-1\n", name, m, n, nnz, base);
|
||||
for (int row = 0; row < m; row++) {
|
||||
const int start = csrRowPtrA[row] - base;
|
||||
const int end = csrRowPtrA[row + 1] - base;
|
||||
for (int colidx = start; colidx < end; colidx++) {
|
||||
const int col = csrColIndA[colidx] - base;
|
||||
const float Areg = csrValA[colidx];
|
||||
printf("%s(%d,%d) = %f\n", name, row + 1, col + 1, Areg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
// CHECK: hipsparseHandle_t handle = NULL;
|
||||
cusparseHandle_t handle = NULL;
|
||||
// CHECK: hipStream_t stream = NULL;
|
||||
cudaStream_t stream = NULL;
|
||||
// CHECK: hipsparseMatDescr_t descrA = NULL;
|
||||
cusparseMatDescr_t descrA = NULL;
|
||||
// CHECK: hipsparseMatDescr_t descrC = NULL;
|
||||
cusparseMatDescr_t descrC = NULL;
|
||||
pruneInfo_t info = NULL;
|
||||
// CHECK: hipsparseStatus_t status = HIPSPARSE_STATUS_SUCCESS;
|
||||
cusparseStatus_t status = CUSPARSE_STATUS_SUCCESS;
|
||||
// CHECK: hipError_t cudaStat1 = hipSuccess;
|
||||
cudaError_t cudaStat1 = cudaSuccess;
|
||||
const int m = 4;
|
||||
const int n = 4;
|
||||
const int nnzA = 9;
|
||||
/*
|
||||
* | 1 0 2 -3 |
|
||||
* | 0 4 0 0 |
|
||||
* A = | 5 0 6 7 |
|
||||
* | 0 8 0 9 |
|
||||
*
|
||||
*/
|
||||
|
||||
const int csrRowPtrA[m + 1] = { 1, 4, 5, 8, 10 };
|
||||
const int csrColIndA[nnzA] = { 1, 3, 4, 2, 1, 3, 4, 2, 4 };
|
||||
const float csrValA[nnzA] = { 1, 2, -3, 4, 5, 6, 7, 8, 9 };
|
||||
|
||||
int* csrRowPtrC = NULL;
|
||||
int* csrColIndC = NULL;
|
||||
float* csrValC = NULL;
|
||||
|
||||
int *d_csrRowPtrA = NULL;
|
||||
int *d_csrColIndA = NULL;
|
||||
float *d_csrValA = NULL;
|
||||
|
||||
int *d_csrRowPtrC = NULL;
|
||||
int *d_csrColIndC = NULL;
|
||||
float *d_csrValC = NULL;
|
||||
|
||||
size_t lworkInBytes = 0;
|
||||
char *d_work = NULL;
|
||||
|
||||
int nnzC = 0;
|
||||
|
||||
float percentage = 20; /* remove 20% of nonzeros */
|
||||
|
||||
printf("example of pruneCsr2csrByPercentage \n");
|
||||
|
||||
printf("prune %.1f percent of nonzeros \n", percentage);
|
||||
|
||||
/* step 1: create cusparse handle, bind a stream */
|
||||
// CHECK: cudaStat1 = hipStreamCreateWithFlags(&stream, hipStreamNonBlocking);
|
||||
cudaStat1 = cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: status = hipsparseCreate(&handle);
|
||||
status = cusparseCreate(&handle);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: status = hipsparseSetStream(handle, stream);
|
||||
status = cusparseSetStream(handle, stream);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// TODO: status = hipsparseCreatePruneInfo(&info);
|
||||
status = cusparseCreatePruneInfo(&info);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
/* step 2: configuration of matrix C */
|
||||
// CHECK: status = hipsparseCreateMatDescr(&descrA);
|
||||
status = cusparseCreateMatDescr(&descrA);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
/* A is base-1*/
|
||||
// CHECK: hipsparseSetMatIndexBase(descrA, HIPSPARSE_INDEX_BASE_ONE);
|
||||
cusparseSetMatIndexBase(descrA, CUSPARSE_INDEX_BASE_ONE);
|
||||
// CHECK: hipsparseSetMatType(descrA, HIPSPARSE_MATRIX_TYPE_GENERAL);
|
||||
cusparseSetMatType(descrA, CUSPARSE_MATRIX_TYPE_GENERAL);
|
||||
// CHECK: status = hipsparseCreateMatDescr(&descrC);
|
||||
status = cusparseCreateMatDescr(&descrC);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
/* C is base-0 */
|
||||
// CHECK: hipsparseSetMatIndexBase(descrC, HIPSPARSE_INDEX_BASE_ZERO);
|
||||
cusparseSetMatIndexBase(descrC, CUSPARSE_INDEX_BASE_ZERO);
|
||||
// CHECK: hipsparseSetMatType(descrC, HIPSPARSE_MATRIX_TYPE_GENERAL);
|
||||
cusparseSetMatType(descrC, CUSPARSE_MATRIX_TYPE_GENERAL);
|
||||
|
||||
printCsr(m, n, nnzA, descrA, csrValA, csrRowPtrA, csrColIndA, "A");
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrRowPtrA, sizeof(int)*(m + 1));
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrRowPtrA, sizeof(int)*(m + 1));
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrColIndA, sizeof(int)*nnzA);
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrColIndA, sizeof(int)*nnzA);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrValA, sizeof(float)*nnzA);
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrValA, sizeof(float)*nnzA);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrRowPtrC, sizeof(int)*(m + 1));
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrRowPtrC, sizeof(int)*(m + 1));
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_csrRowPtrA, csrRowPtrA, sizeof(int)*(m + 1), hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_csrRowPtrA, csrRowPtrA, sizeof(int)*(m + 1), cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_csrColIndA, csrColIndA, sizeof(int)*nnzA, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_csrColIndA, csrColIndA, sizeof(int)*nnzA, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_csrValA, csrValA, sizeof(float)*nnzA, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_csrValA, csrValA, sizeof(float)*nnzA, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 3: query workspace */
|
||||
// TODO: status = hipsparseSpruneCsr2csrByPercentage_bufferSizeExt(
|
||||
status = cusparseSpruneCsr2csrByPercentage_bufferSizeExt(
|
||||
handle,
|
||||
m,
|
||||
n,
|
||||
nnzA,
|
||||
descrA,
|
||||
d_csrValA,
|
||||
d_csrRowPtrA,
|
||||
d_csrColIndA,
|
||||
percentage,
|
||||
descrC,
|
||||
d_csrValC,
|
||||
d_csrRowPtrC,
|
||||
d_csrColIndC,
|
||||
info,
|
||||
&lworkInBytes);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
printf("lworkInBytes = %lld \n", (long long)lworkInBytes);
|
||||
// CHECK: if (NULL != d_work) { hipFree(d_work); }
|
||||
if (NULL != d_work) { cudaFree(d_work); }
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_work, lworkInBytes);
|
||||
cudaStat1 = cudaMalloc((void**)&d_work, lworkInBytes);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 4: compute csrRowPtrC and nnzC */
|
||||
// TODO: status = hipsparseSpruneCsr2csrNnzByPercentage(
|
||||
status = cusparseSpruneCsr2csrNnzByPercentage(
|
||||
handle,
|
||||
m,
|
||||
n,
|
||||
nnzA,
|
||||
descrA,
|
||||
d_csrValA,
|
||||
d_csrRowPtrA,
|
||||
d_csrColIndA,
|
||||
percentage,
|
||||
descrC,
|
||||
d_csrRowPtrC,
|
||||
&nnzC, /* host */
|
||||
info,
|
||||
d_work);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: cudaStat1 = hipDeviceSynchronize();
|
||||
cudaStat1 = cudaDeviceSynchronize();
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
printf("nnzC = %d\n", nnzC);
|
||||
if (0 == nnzC) {
|
||||
printf("C is empty \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* step 5: compute csrColIndC and csrValC */
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrColIndC, sizeof(int) * nnzC);
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrColIndC, sizeof(int) * nnzC);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrValC, sizeof(float) * nnzC);
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrValC, sizeof(float) * nnzC);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// TODO: status = hipsparseSpruneCsr2csrByPercentage(
|
||||
status = cusparseSpruneCsr2csrByPercentage(
|
||||
handle,
|
||||
m,
|
||||
n,
|
||||
nnzA,
|
||||
descrA,
|
||||
d_csrValA,
|
||||
d_csrRowPtrA,
|
||||
d_csrColIndA,
|
||||
percentage,
|
||||
descrC,
|
||||
d_csrValC,
|
||||
d_csrRowPtrC,
|
||||
d_csrColIndC,
|
||||
info,
|
||||
d_work);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: cudaStat1 = hipDeviceSynchronize();
|
||||
cudaStat1 = cudaDeviceSynchronize();
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 6: output C */
|
||||
csrRowPtrC = (int*)malloc(sizeof(int)*(m + 1));
|
||||
csrColIndC = (int*)malloc(sizeof(int)*nnzC);
|
||||
csrValC = (float*)malloc(sizeof(float)*nnzC);
|
||||
assert(NULL != csrRowPtrC);
|
||||
assert(NULL != csrColIndC);
|
||||
assert(NULL != csrValC);
|
||||
// CHECK: cudaStat1 = hipMemcpy(csrRowPtrC, d_csrRowPtrC, sizeof(int)*(m + 1), hipMemcpyDeviceToHost);
|
||||
cudaStat1 = cudaMemcpy(csrRowPtrC, d_csrRowPtrC, sizeof(int)*(m + 1), cudaMemcpyDeviceToHost);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(csrColIndC, d_csrColIndC, sizeof(int)*nnzC, hipMemcpyDeviceToHost);
|
||||
cudaStat1 = cudaMemcpy(csrColIndC, d_csrColIndC, sizeof(int)*nnzC, cudaMemcpyDeviceToHost);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(csrValC, d_csrValC, sizeof(float)*nnzC, hipMemcpyDeviceToHost);
|
||||
cudaStat1 = cudaMemcpy(csrValC, d_csrValC, sizeof(float)*nnzC, cudaMemcpyDeviceToHost);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
printCsr(m, n, nnzC, descrC, csrValC, csrRowPtrC, csrColIndC, "C");
|
||||
|
||||
/* free resources */
|
||||
// CHECK: if (d_csrRowPtrA) hipFree(d_csrRowPtrA);
|
||||
if (d_csrRowPtrA) cudaFree(d_csrRowPtrA);
|
||||
// CHECK: if (d_csrColIndA) hipFree(d_csrColIndA);
|
||||
if (d_csrColIndA) cudaFree(d_csrColIndA);
|
||||
// CHECK: if (d_csrValA) hipFree(d_csrValA);
|
||||
if (d_csrValA) cudaFree(d_csrValA);
|
||||
// CHECK: if (d_csrRowPtrC) hipFree(d_csrRowPtrC);
|
||||
if (d_csrRowPtrC) cudaFree(d_csrRowPtrC);
|
||||
// CHECK: if (d_csrColIndC) hipFree(d_csrColIndC);
|
||||
if (d_csrColIndC) cudaFree(d_csrColIndC);
|
||||
// CHECK: if (d_csrValC) hipFree(d_csrValC);
|
||||
if (d_csrValC) cudaFree(d_csrValC);
|
||||
|
||||
if (csrRowPtrC) free(csrRowPtrC);
|
||||
if (csrColIndC) free(csrColIndC);
|
||||
if (csrValC) free(csrValC);
|
||||
// CHECK: if (handle) hipsparseDestroy(handle);
|
||||
if (handle) cusparseDestroy(handle);
|
||||
// CHECK: if (stream) hipStreamDestroy(stream);
|
||||
if (stream) cudaStreamDestroy(stream);
|
||||
// CHECK: if (descrA) hipsparseDestroyMatDescr(descrA);
|
||||
if (descrA) cusparseDestroyMatDescr(descrA);
|
||||
// CHECK: if (descrC) hipsparseDestroyMatDescr(descrC);
|
||||
if (descrC) cusparseDestroyMatDescr(descrC);
|
||||
// TODO: if (info) hipsparseDestroyPruneInfo(info);
|
||||
if (info) cusparseDestroyPruneInfo(info);
|
||||
// CHECK: hipDeviceReset();
|
||||
cudaDeviceReset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,413 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include <hipsparse.h>
|
||||
#include <cusparse.h>
|
||||
// CHECK: #include <hipblas.h>
|
||||
#include <cublas_v2.h>
|
||||
|
||||
// NOTE: CUDA 10.0
|
||||
|
||||
/*
|
||||
* compute | b - A*x|_inf
|
||||
*/
|
||||
void residaul_eval(
|
||||
int n,
|
||||
const float *dl,
|
||||
const float *d,
|
||||
const float *du,
|
||||
const float *b,
|
||||
const float *x,
|
||||
float *r_nrminf_ptr)
|
||||
{
|
||||
float r_nrminf = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
float dot = 0;
|
||||
if (i > 0) {
|
||||
dot += dl[i] * x[i - 1];
|
||||
}
|
||||
dot += d[i] * x[i];
|
||||
if (i < (n - 1)) {
|
||||
dot += du[i] * x[i + 1];
|
||||
}
|
||||
float ri = b[i] - dot;
|
||||
r_nrminf = (r_nrminf > fabs(ri)) ? r_nrminf : fabs(ri);
|
||||
}
|
||||
|
||||
*r_nrminf_ptr = r_nrminf;
|
||||
}
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
// CHECK: hipsparseHandle_t cusparseH = NULL;
|
||||
cusparseHandle_t cusparseH = NULL;
|
||||
// CHECK: hipblasHandle_t cublasH = NULL;
|
||||
cublasHandle_t cublasH = NULL;
|
||||
// CHECK: hipStream_t stream = NULL;
|
||||
cudaStream_t stream = NULL;
|
||||
// CHECK: hipsparseStatus_t status = HIPSPARSE_STATUS_SUCCESS;
|
||||
cusparseStatus_t status = CUSPARSE_STATUS_SUCCESS;
|
||||
// CHECK: hipblasStatus_t cublasStat = HIPBLAS_STATUS_SUCCESS;
|
||||
cublasStatus_t cublasStat = CUBLAS_STATUS_SUCCESS;
|
||||
// CHECK: hipError_t cudaStat1 = hipSuccess;
|
||||
cudaError_t cudaStat1 = cudaSuccess;
|
||||
|
||||
const int n = 3;
|
||||
const int batchSize = 2;
|
||||
/*
|
||||
* | 1 6 0 | | 1 | | -0.603960 |
|
||||
* A1 =| 4 2 7 |, b1 = | 2 |, x1 = | 0.267327 |
|
||||
* | 0 5 3 | | 3 | | 0.554455 |
|
||||
*
|
||||
* | 8 13 0 | | 4 | | -0.063291 |
|
||||
* A2 =| 11 9 14 |, b2 = | 5 |, x2 = | 0.346641 |
|
||||
* | 0 12 10 | | 6 | | 0.184031 |
|
||||
*/
|
||||
|
||||
/*
|
||||
* A = (dl, d, du), B and X are in aggregate format
|
||||
*/
|
||||
const float dl[n * batchSize] = { 0, 4, 5, 0, 11, 12 };
|
||||
const float d[n * batchSize] = { 1, 2, 3, 8, 9, 10 };
|
||||
const float du[n * batchSize] = { 6, 7, 0, 13, 14, 0 };
|
||||
const float B[n * batchSize] = { 1, 2, 3, 4, 5, 6 };
|
||||
float X[n * batchSize]; /* Xj = Aj \ Bj */
|
||||
|
||||
/* device memory
|
||||
* (d_dl0, d_d0, d_du0) is aggregate format
|
||||
* (d_dl, d_d, d_du) is interleaved format
|
||||
*/
|
||||
float *d_dl0 = NULL;
|
||||
float *d_d0 = NULL;
|
||||
float *d_du0 = NULL;
|
||||
float *d_dl = NULL;
|
||||
float *d_d = NULL;
|
||||
float *d_du = NULL;
|
||||
float *d_B = NULL;
|
||||
float *d_X = NULL;
|
||||
|
||||
size_t lworkInBytes = 0;
|
||||
char *d_work = NULL;
|
||||
|
||||
/*
|
||||
* algo = 0: cuThomas (unstable)
|
||||
* algo = 1: LU with pivoting (stable)
|
||||
* algo = 2: QR (stable)
|
||||
*/
|
||||
const int algo = 2;
|
||||
|
||||
const float h_one = 1;
|
||||
const float h_zero = 0;
|
||||
|
||||
printf("example of gtsv (interleaved format) \n");
|
||||
printf("choose algo = 0,1,2 to select different algorithms \n");
|
||||
printf("n = %d, batchSize = %d, algo = %d \n", n, batchSize, algo);
|
||||
|
||||
/* step 1: create cusparse/cublas handle, bind a stream */
|
||||
// CHECK: cudaStat1 = hipStreamCreateWithFlags(&stream, hipStreamNonBlocking);
|
||||
cudaStat1 = cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: status = hipsparseCreate(&cusparseH);
|
||||
status = cusparseCreate(&cusparseH);
|
||||
//CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: status = hipsparseSetStream(cusparseH, stream);
|
||||
status = cusparseSetStream(cusparseH, stream);
|
||||
//CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: cublasStat = hipblasCreate(&cublasH);
|
||||
cublasStat = cublasCreate(&cublasH);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
// CHECK: cublasStat = hipblasSetStream(cublasH, stream);
|
||||
cublasStat = cublasSetStream(cublasH, stream);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
|
||||
/* step 2: allocate device memory */
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_dl0, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_dl0, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_d0, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_d0, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_du0, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_du0, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_dl, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_dl, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_d, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_d, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_du, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_du, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_B, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_B, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_X, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_X, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 3: prepare data in device, interleaved format */
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_dl0, dl, sizeof(float)*n*batchSize, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_dl0, dl, sizeof(float)*n*batchSize, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_d0, d, sizeof(float)*n*batchSize, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_d0, d, sizeof(float)*n*batchSize, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_du0, du, sizeof(float)*n*batchSize, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_du0, du, sizeof(float)*n*batchSize, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_B, B, sizeof(float)*n*batchSize, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_B, B, sizeof(float)*n*batchSize, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
/* convert dl to interleaved format
|
||||
* dl = transpose(dl0)
|
||||
*/
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
batchSize, /* number of rows of dl */
|
||||
n, /* number of columns of dl */
|
||||
&h_one,
|
||||
d_dl0, /* dl0 is n-by-batchSize */
|
||||
n, /* leading dimension of dl0 */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't cae */
|
||||
d_dl, /* dl is batchSize-by-n */
|
||||
batchSize /* leading dimension of dl */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
/* convert d to interleaved format
|
||||
* d = transpose(d0)
|
||||
*/
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
batchSize, /* number of rows of d */
|
||||
n, /* number of columns of d */
|
||||
&h_one,
|
||||
d_d0, /* d0 is n-by-batchSize */
|
||||
n, /* leading dimension of d0 */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't cae */
|
||||
d_d, /* d is batchSize-by-n */
|
||||
batchSize /* leading dimension of d */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
|
||||
/* convert du to interleaved format
|
||||
* du = transpose(du0)
|
||||
*/
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
batchSize, /* number of rows of du */
|
||||
n, /* number of columns of du */
|
||||
&h_one,
|
||||
d_du0, /* du0 is n-by-batchSize */
|
||||
n, /* leading dimension of du0 */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't cae */
|
||||
d_du, /* du is batchSize-by-n */
|
||||
batchSize /* leading dimension of du */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
|
||||
/* convert B to interleaved format
|
||||
* X = transpose(B)
|
||||
*/
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
batchSize, /* number of rows of X */
|
||||
n, /* number of columns of X */
|
||||
&h_one,
|
||||
d_B, /* B is n-by-batchSize */
|
||||
n, /* leading dimension of B */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't cae */
|
||||
d_X, /* X is batchSize-by-n */
|
||||
batchSize /* leading dimension of X */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
/* step 4: prepare workspace */
|
||||
// NOTE: CUDA 10.0
|
||||
// TODO: status = hipsparseSgtsvInterleavedBatch_bufferSizeExt(
|
||||
status = cusparseSgtsvInterleavedBatch_bufferSizeExt(
|
||||
cusparseH,
|
||||
algo,
|
||||
n,
|
||||
d_dl,
|
||||
d_d,
|
||||
d_du,
|
||||
d_X,
|
||||
batchSize,
|
||||
&lworkInBytes);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
printf("lworkInBytes = %lld \n", (long long)lworkInBytes);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_work, lworkInBytes);
|
||||
cudaStat1 = cudaMalloc((void**)&d_work, lworkInBytes);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 5: solve Aj*xj = bj */
|
||||
// NOTE: CUDA 10.0
|
||||
// TODO: status = hipsparseSgtsvInterleavedBatch(
|
||||
status = cusparseSgtsvInterleavedBatch(
|
||||
cusparseH,
|
||||
algo,
|
||||
n,
|
||||
d_dl,
|
||||
d_d,
|
||||
d_du,
|
||||
d_X,
|
||||
batchSize,
|
||||
d_work);
|
||||
// CHECK: cudaStat1 = hipDeviceSynchronize();
|
||||
cudaStat1 = cudaDeviceSynchronize();
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 6: convert X back to aggregate format */
|
||||
/* B = transpose(X) */
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
n, /* number of rows of B */
|
||||
batchSize, /* number of columns of B */
|
||||
&h_one,
|
||||
d_X, /* X is batchSize-by-n */
|
||||
batchSize, /* leading dimension of X */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't cae */
|
||||
d_B, /* B is n-by-batchSize */
|
||||
n /* leading dimension of B */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
/* step 7: residual evaluation */
|
||||
// CHECK: cudaStat1 = hipMemcpy(X, d_B, sizeof(float)*n*batchSize, hipMemcpyDeviceToHost);
|
||||
cudaStat1 = cudaMemcpy(X, d_B, sizeof(float)*n*batchSize, cudaMemcpyDeviceToHost);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
printf("==== x1 = inv(A1)*b1 \n");
|
||||
for (int j = 0; j < n; j++) {
|
||||
printf("x1[%d] = %f\n", j, X[j]);
|
||||
}
|
||||
|
||||
float r1_nrminf;
|
||||
residaul_eval(
|
||||
n,
|
||||
dl,
|
||||
d,
|
||||
du,
|
||||
B,
|
||||
X,
|
||||
&r1_nrminf
|
||||
);
|
||||
printf("|b1 - A1*x1| = %E\n", r1_nrminf);
|
||||
|
||||
printf("\n==== x2 = inv(A2)*b2 \n");
|
||||
for (int j = 0; j < n; j++) {
|
||||
printf("x2[%d] = %f\n", j, X[n + j]);
|
||||
}
|
||||
|
||||
float r2_nrminf;
|
||||
residaul_eval(
|
||||
n,
|
||||
dl + n,
|
||||
d + n,
|
||||
du + n,
|
||||
B + n,
|
||||
X + n,
|
||||
&r2_nrminf
|
||||
);
|
||||
printf("|b2 - A2*x2| = %E\n", r2_nrminf);
|
||||
|
||||
/* free resources */
|
||||
// CHECK: if (d_dl0) hipFree(d_dl0);
|
||||
if (d_dl0) cudaFree(d_dl0);
|
||||
// CHECK: if (d_d0) hipFree(d_d0);
|
||||
if (d_d0) cudaFree(d_d0);
|
||||
// CHECK: if (d_du0) hipFree(d_du0);
|
||||
if (d_du0) cudaFree(d_du0);
|
||||
// CHECK: if (d_dl) hipFree(d_dl);
|
||||
if (d_dl) cudaFree(d_dl);
|
||||
// CHECK: if (d_d) hipFree(d_d);
|
||||
if (d_d) cudaFree(d_d);
|
||||
// CHECK: if (d_du) hipFree(d_du);
|
||||
if (d_du) cudaFree(d_du);
|
||||
// CHECK: if (d_B) hipFree(d_B);
|
||||
if (d_B) cudaFree(d_B);
|
||||
// CHECK: if (d_X) hipFree(d_X);
|
||||
if (d_X) cudaFree(d_X);
|
||||
// CHECK: if (cusparseH) hipsparseDestroy(cusparseH);
|
||||
if (cusparseH) cusparseDestroy(cusparseH);
|
||||
// CHECK: if (cublasH) hipblasDestroy(cublasH);
|
||||
if (cublasH) cublasDestroy(cublasH);
|
||||
// CHECK: if (stream) hipStreamDestroy(stream);
|
||||
if (stream) cudaStreamDestroy(stream);
|
||||
// CHECK: hipDeviceReset();
|
||||
cudaDeviceReset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,414 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include <hipsparse.h>
|
||||
#include <cusparse.h>
|
||||
// CHECK: #include <hipblas.h>
|
||||
#include <cublas_v2.h>
|
||||
|
||||
// NOTE: CUDA 10.0
|
||||
|
||||
/*
|
||||
* compute | b - A*x|_inf
|
||||
*/
|
||||
void residaul_eval(
|
||||
int n,
|
||||
const float *dl,
|
||||
const float *d,
|
||||
const float *du,
|
||||
const float *b,
|
||||
const float *x,
|
||||
float *r_nrminf_ptr)
|
||||
{
|
||||
float r_nrminf = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
float dot = 0;
|
||||
if (i > 0) {
|
||||
dot += dl[i] * x[i - 1];
|
||||
}
|
||||
dot += d[i] * x[i];
|
||||
if (i < (n - 1)) {
|
||||
dot += du[i] * x[i + 1];
|
||||
}
|
||||
float ri = b[i] - dot;
|
||||
r_nrminf = (r_nrminf > fabs(ri)) ? r_nrminf : fabs(ri);
|
||||
}
|
||||
|
||||
*r_nrminf_ptr = r_nrminf;
|
||||
}
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
// CHECK: hipsparseHandle_t cusparseH = NULL;
|
||||
cusparseHandle_t cusparseH = NULL;
|
||||
// CHECK: hipblasHandle_t cublasH = NULL;
|
||||
cublasHandle_t cublasH = NULL;
|
||||
// CHECK: hipStream_t stream = NULL;
|
||||
cudaStream_t stream = NULL;
|
||||
// CHECK: hipsparseStatus_t status = HIPSPARSE_STATUS_SUCCESS;
|
||||
cusparseStatus_t status = CUSPARSE_STATUS_SUCCESS;
|
||||
// CHECK: hipblasStatus_t cublasStat = HIPBLAS_STATUS_SUCCESS;
|
||||
cublasStatus_t cublasStat = CUBLAS_STATUS_SUCCESS;
|
||||
// CHECK: hipError_t cudaStat1 = hipSuccess;
|
||||
cudaError_t cudaStat1 = cudaSuccess;
|
||||
|
||||
const int n = 3;
|
||||
const int batchSize = 2;
|
||||
/*
|
||||
* | 1 6 0 | | 1 | | -0.603960 |
|
||||
* A1 =| 4 2 7 |, b1 = | 2 |, x1 = | 0.267327 |
|
||||
* | 0 5 3 | | 3 | | 0.554455 |
|
||||
*
|
||||
* | 8 13 0 | | 4 | | -0.063291 |
|
||||
* A2 =| 11 9 14 |, b2 = | 5 |, x2 = | 0.346641 |
|
||||
* | 0 12 10 | | 6 | | 0.184031 |
|
||||
*/
|
||||
|
||||
/*
|
||||
* A = (dl, d, du), B and X are in aggregate format
|
||||
*/
|
||||
const float dl[n * batchSize] = { 0, 4, 5, 0, 11, 12 };
|
||||
const float d[n * batchSize] = { 1, 2, 3, 8, 9, 10 };
|
||||
const float du[n * batchSize] = { 6, 7, 0, 13, 14, 0 };
|
||||
const float B[n * batchSize] = { 1, 2, 3, 4, 5, 6 };
|
||||
float X[n * batchSize]; /* Xj = Aj \ Bj */
|
||||
|
||||
/* device memory
|
||||
* (d_dl0, d_d0, d_du0) is aggregate format
|
||||
* (d_dl, d_d, d_du) is interleaved format
|
||||
*/
|
||||
float *d_dl0 = NULL;
|
||||
float *d_d0 = NULL;
|
||||
float *d_du0 = NULL;
|
||||
float *d_dl = NULL;
|
||||
float *d_d = NULL;
|
||||
float *d_du = NULL;
|
||||
float *d_B = NULL;
|
||||
float *d_X = NULL;
|
||||
|
||||
size_t lworkInBytes = 0;
|
||||
char *d_work = NULL;
|
||||
|
||||
/*
|
||||
* algo = 0: cuThomas (unstable)
|
||||
* algo = 1: LU with pivoting (stable)
|
||||
* algo = 2: QR (stable)
|
||||
*/
|
||||
const int algo = 2;
|
||||
|
||||
const float h_one = 1;
|
||||
const float h_zero = 0;
|
||||
|
||||
printf("example of gtsv (interleaved format) \n");
|
||||
printf("choose algo = 0,1,2 to select different algorithms \n");
|
||||
printf("n = %d, batchSize = %d, algo = %d \n", n, batchSize, algo);
|
||||
|
||||
/* step 1: create cusparse/cublas handle, bind a stream */
|
||||
// CHECK: cudaStat1 = hipStreamCreateWithFlags(&stream, hipStreamNonBlocking);
|
||||
cudaStat1 = cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: status = hipsparseCreate(&cusparseH);
|
||||
status = cusparseCreate(&cusparseH);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: status = hipsparseSetStream(cusparseH, stream);
|
||||
status = cusparseSetStream(cusparseH, stream);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: cublasStat = hipblasCreate(&cublasH);
|
||||
cublasStat = cublasCreate(&cublasH);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
// CHECK: cublasStat = hipblasSetStream(cublasH, stream);
|
||||
cublasStat = cublasSetStream(cublasH, stream);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
|
||||
/* step 2: allocate device memory */
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_dl0, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_dl0, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_d0, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_d0, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_du0, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_du0, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_dl, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_dl, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_d, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_d, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_du, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_du, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_B, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_B, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_X, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_X, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 3: prepare data in device, interleaved format */
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_dl0, dl, sizeof(float)*n*batchSize, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_dl0, dl, sizeof(float)*n*batchSize, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_d0, d, sizeof(float)*n*batchSize, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_d0, d, sizeof(float)*n*batchSize, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_du0, du, sizeof(float)*n*batchSize, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_du0, du, sizeof(float)*n*batchSize, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_B, B, sizeof(float)*n*batchSize, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_B, B, sizeof(float)*n*batchSize, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
/* convert dl to interleaved format
|
||||
* dl = transpose(dl0)
|
||||
*/
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
batchSize, /* number of rows of dl */
|
||||
n, /* number of columns of dl */
|
||||
&h_one,
|
||||
d_dl0, /* dl0 is n-by-batchSize */
|
||||
n, /* leading dimension of dl0 */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't care */
|
||||
d_dl, /* dl is batchSize-by-n */
|
||||
batchSize /* leading dimension of dl */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
/* convert d to interleaved format
|
||||
* d = transpose(d0)
|
||||
*/
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T
|
||||
// CHECK: HIPBLAS_OP_T
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
batchSize, /* number of rows of d */
|
||||
n, /* number of columns of d */
|
||||
&h_one,
|
||||
d_d0, /* d0 is n-by-batchSize */
|
||||
n, /* leading dimension of d0 */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't cae */
|
||||
d_d, /* d is batchSize-by-n */
|
||||
batchSize /* leading dimension of d */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
|
||||
/* convert du to interleaved format
|
||||
* du = transpose(du0)
|
||||
*/
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T
|
||||
// CHECK: HIPBLAS_OP_T
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
batchSize, /* number of rows of du */
|
||||
n, /* number of columns of du */
|
||||
&h_one,
|
||||
d_du0, /* du0 is n-by-batchSize */
|
||||
n, /* leading dimension of du0 */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't cae */
|
||||
d_du, /* du is batchSize-by-n */
|
||||
batchSize /* leading dimension of du */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
|
||||
/* convert B to interleaved format
|
||||
* X = transpose(B)
|
||||
*/
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T
|
||||
// CHECK: HIPBLAS_OP_T
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
batchSize, /* number of rows of X */
|
||||
n, /* number of columns of X */
|
||||
&h_one,
|
||||
d_B, /* B is n-by-batchSize */
|
||||
n, /* leading dimension of B */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't cae */
|
||||
d_X, /* X is batchSize-by-n */
|
||||
batchSize /* leading dimension of X */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
/* step 4: prepare workspace */
|
||||
// NOTE: CUDA 10.0
|
||||
// TODO: status = hipsparseSgtsvInterleavedBatch_bufferSizeExt(
|
||||
status = cusparseSgtsvInterleavedBatch_bufferSizeExt(
|
||||
cusparseH,
|
||||
algo,
|
||||
n,
|
||||
d_dl,
|
||||
d_d,
|
||||
d_du,
|
||||
d_X,
|
||||
batchSize,
|
||||
&lworkInBytes);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
printf("lworkInBytes = %lld \n", (long long)lworkInBytes);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_work, lworkInBytes);
|
||||
cudaStat1 = cudaMalloc((void**)&d_work, lworkInBytes);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 5: solve Aj*xj = bj */
|
||||
// NOTE: CUDA 10.0
|
||||
// TODO: status = hipsparseSgtsvInterleavedBatch(
|
||||
status = cusparseSgtsvInterleavedBatch(
|
||||
cusparseH,
|
||||
algo,
|
||||
n,
|
||||
d_dl,
|
||||
d_d,
|
||||
d_du,
|
||||
d_X,
|
||||
batchSize,
|
||||
d_work);
|
||||
// CHECK: cudaStat1 = hipDeviceSynchronize();
|
||||
cudaStat1 = cudaDeviceSynchronize();
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 6: convert X back to aggregate format */
|
||||
/* B = transpose(X) */
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T
|
||||
// CHECK: HIPBLAS_OP_T
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
n, /* number of rows of B */
|
||||
batchSize, /* number of columns of B */
|
||||
&h_one,
|
||||
d_X, /* X is batchSize-by-n */
|
||||
batchSize, /* leading dimension of X */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't cae */
|
||||
d_B, /* B is n-by-batchSize */
|
||||
n /* leading dimension of B */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
/* step 7: residual evaluation */
|
||||
// CHECK: cudaStat1 = hipMemcpy(X, d_B, sizeof(float)*n*batchSize, hipMemcpyDeviceToHost);
|
||||
cudaStat1 = cudaMemcpy(X, d_B, sizeof(float)*n*batchSize, cudaMemcpyDeviceToHost);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
printf("==== x1 = inv(A1)*b1 \n");
|
||||
for (int j = 0; j < n; j++) {
|
||||
printf("x1[%d] = %f\n", j, X[j]);
|
||||
}
|
||||
|
||||
float r1_nrminf;
|
||||
residaul_eval(
|
||||
n,
|
||||
dl,
|
||||
d,
|
||||
du,
|
||||
B,
|
||||
X,
|
||||
&r1_nrminf
|
||||
);
|
||||
printf("|b1 - A1*x1| = %E\n", r1_nrminf);
|
||||
|
||||
printf("\n==== x2 = inv(A2)*b2 \n");
|
||||
for (int j = 0; j < n; j++) {
|
||||
printf("x2[%d] = %f\n", j, X[n + j]);
|
||||
}
|
||||
|
||||
float r2_nrminf;
|
||||
residaul_eval(
|
||||
n,
|
||||
dl + n,
|
||||
d + n,
|
||||
du + n,
|
||||
B + n,
|
||||
X + n,
|
||||
&r2_nrminf
|
||||
);
|
||||
printf("|b2 - A2*x2| = %E\n", r2_nrminf);
|
||||
|
||||
/* free resources */
|
||||
// CHECK: if (d_dl0) hipFree(d_dl0);
|
||||
if (d_dl0) cudaFree(d_dl0);
|
||||
// CHECK: if (d_d0) hipFree(d_d0);
|
||||
if (d_d0) cudaFree(d_d0);
|
||||
// CHECK: if (d_du0) hipFree(d_du0);
|
||||
if (d_du0) cudaFree(d_du0);
|
||||
// CHECK: if (d_dl) hipFree(d_dl);
|
||||
if (d_dl) cudaFree(d_dl);
|
||||
// CHECK: if (d_d) hipFree(d_d);
|
||||
if (d_d) cudaFree(d_d);
|
||||
// CHECK: if (d_du) hipFree(d_du);
|
||||
if (d_du) cudaFree(d_du);
|
||||
// CHECK: if (d_B) hipFree(d_B);
|
||||
if (d_B) cudaFree(d_B);
|
||||
// CHECK: if (d_X) hipFree(d_X);
|
||||
if (d_X) cudaFree(d_X);
|
||||
// CHECK: if (cusparseH) hipsparseDestroy(cusparseH);
|
||||
if (cusparseH) cusparseDestroy(cusparseH);
|
||||
// CHECK: if (cublasH) hipblasDestroy(cublasH);
|
||||
if (cublasH) cublasDestroy(cublasH);
|
||||
// CHECK: if (stream) hipStreamDestroy(stream);
|
||||
if (stream) cudaStreamDestroy(stream);
|
||||
// CHECK: hipDeviceReset();
|
||||
cudaDeviceReset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,507 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include <hipsparse.h>
|
||||
#include <cusparse.h>
|
||||
// CHECK: #include <hipblas.h>
|
||||
#include <cublas_v2.h>
|
||||
|
||||
// NOTE: CUDA 10.0
|
||||
|
||||
/*
|
||||
* compute | b - A*x|_inf
|
||||
*/
|
||||
void residaul_eval(
|
||||
int n,
|
||||
const float *ds,
|
||||
const float *dl,
|
||||
const float *d,
|
||||
const float *du,
|
||||
const float *dw,
|
||||
const float *b,
|
||||
const float *x,
|
||||
float *r_nrminf_ptr)
|
||||
{
|
||||
float r_nrminf = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
float dot = 0;
|
||||
if (i > 1) {
|
||||
dot += ds[i] * x[i - 2];
|
||||
}
|
||||
if (i > 0) {
|
||||
dot += dl[i] * x[i - 1];
|
||||
}
|
||||
dot += d[i] * x[i];
|
||||
if (i < (n - 1)) {
|
||||
dot += du[i] * x[i + 1];
|
||||
}
|
||||
if (i < (n - 2)) {
|
||||
dot += dw[i] * x[i + 2];
|
||||
}
|
||||
float ri = b[i] - dot;
|
||||
r_nrminf = (r_nrminf > fabs(ri)) ? r_nrminf : fabs(ri);
|
||||
}
|
||||
|
||||
*r_nrminf_ptr = r_nrminf;
|
||||
}
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
// CHECK: hipsparseHandle_t cusparseH = NULL;
|
||||
cusparseHandle_t cusparseH = NULL;
|
||||
// CHECK: hipblasHandle_t cublasH = NULL;
|
||||
cublasHandle_t cublasH = NULL;
|
||||
// CHECK: hipStream_t stream = NULL;
|
||||
cudaStream_t stream = NULL;
|
||||
// CHECK: hipsparseStatus_t status = HIPSPARSE_STATUS_SUCCESS;
|
||||
cusparseStatus_t status = CUSPARSE_STATUS_SUCCESS;
|
||||
// CHECK: hipblasStatus_t cublasStat = HIPBLAS_STATUS_SUCCESS;
|
||||
cublasStatus_t cublasStat = CUBLAS_STATUS_SUCCESS;
|
||||
// CHECK: hipError_t cudaStat1 = hipSuccess;
|
||||
cudaError_t cudaStat1 = cudaSuccess;
|
||||
|
||||
const int n = 4;
|
||||
const int batchSize = 2;
|
||||
|
||||
/*
|
||||
* | 1 8 13 0 | | 1 | | -0.0592 |
|
||||
* A1 =| 5 2 9 14 |, b1 = | 2 |, x1 = | 0.3428 |
|
||||
* | 11 6 3 10 | | 3 | | -0.1295 |
|
||||
* | 0 12 7 4 | | 4 | | 0.1982 |
|
||||
*
|
||||
* | 15 22 27 0 | | 5 | | -0.0012 |
|
||||
* A2 =| 19 16 23 28 |, b2 = | 6 |, x2 = | 0.2792 |
|
||||
* | 25 20 17 24 | | 7 | | -0.0416 |
|
||||
* | 0 26 21 18 | | 8 | | 0.0898 |
|
||||
*/
|
||||
|
||||
/*
|
||||
* A = (ds, dl, d, du, dw), B and X are in aggregate format
|
||||
*/
|
||||
const float ds[n * batchSize] = { 0, 0, 11, 12, 0, 0, 25, 26 };
|
||||
const float dl[n * batchSize] = { 0, 5, 6, 7, 0, 19, 20, 21 };
|
||||
const float d[n * batchSize] = { 1, 2, 3, 4, 15, 16, 17, 18 };
|
||||
const float du[n * batchSize] = { 8, 9, 10, 0, 22, 23, 24, 0 };
|
||||
const float dw[n * batchSize] = { 13,14, 0, 0, 27, 28, 0, 0 };
|
||||
const float B[n * batchSize] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
float X[n * batchSize]; /* Xj = Aj \ Bj */
|
||||
|
||||
/* device memory
|
||||
* (d_ds0, d_dl0, d_d0, d_du0, d_dw0) is aggregate format
|
||||
* (d_ds, d_dl, d_d, d_du, d_dw) is interleaved format
|
||||
*/
|
||||
float *d_ds0 = NULL;
|
||||
float *d_dl0 = NULL;
|
||||
float *d_d0 = NULL;
|
||||
float *d_du0 = NULL;
|
||||
float *d_dw0 = NULL;
|
||||
float *d_ds = NULL;
|
||||
float *d_dl = NULL;
|
||||
float *d_d = NULL;
|
||||
float *d_du = NULL;
|
||||
float *d_dw = NULL;
|
||||
float *d_B = NULL;
|
||||
float *d_X = NULL;
|
||||
|
||||
size_t lworkInBytes = 0;
|
||||
char *d_work = NULL;
|
||||
|
||||
const float h_one = 1;
|
||||
const float h_zero = 0;
|
||||
|
||||
int algo = 0; /* QR factorization */
|
||||
|
||||
printf("example of gpsv (interleaved format) \n");
|
||||
printf("n = %d, batchSize = %d\n", n, batchSize);
|
||||
|
||||
/* step 1: create cusparse/cublas handle, bind a stream */
|
||||
// CHECK: cudaStat1 = hipStreamCreateWithFlags(&stream, hipStreamNonBlocking);
|
||||
cudaStat1 = cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: status = hipsparseCreate(&cusparseH);
|
||||
status = cusparseCreate(&cusparseH);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: status = hipsparseSetStream(cusparseH, stream);
|
||||
status = cusparseSetStream(cusparseH, stream);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: cublasStat = hipblasCreate(&cublasH);
|
||||
cublasStat = cublasCreate(&cublasH);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
// CHECK: cublasStat = hipblasSetStream(cublasH, stream);
|
||||
cublasStat = cublasSetStream(cublasH, stream);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
/* step 2: allocate device memory */
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_ds0, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_ds0, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_dl0, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_dl0, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_d0, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_d0, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_du0, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_du0, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_dw0, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_dw0, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_ds, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_ds, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_dl, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_dl, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_d, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_d, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_du, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_du, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_dw, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_dw, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_B, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_B, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_X, sizeof(float)*n*batchSize);
|
||||
cudaStat1 = cudaMalloc((void**)&d_X, sizeof(float)*n*batchSize);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
/* step 3: prepare data in device, interleaved format */
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_ds0, ds, sizeof(float)*n*batchSize, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_ds0, ds, sizeof(float)*n*batchSize, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_dl0, dl, sizeof(float)*n*batchSize, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_dl0, dl, sizeof(float)*n*batchSize, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_d0, d, sizeof(float)*n*batchSize, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_d0, d, sizeof(float)*n*batchSize, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_du0, du, sizeof(float)*n*batchSize, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_du0, du, sizeof(float)*n*batchSize, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_dw0, dw, sizeof(float)*n*batchSize, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_dw0, dw, sizeof(float)*n*batchSize, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_B, B, sizeof(float)*n*batchSize, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_B, B, sizeof(float)*n*batchSize, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
/* convert ds to interleaved format
|
||||
* ds = transpose(ds0) */
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
batchSize, /* number of rows of ds */
|
||||
n, /* number of columns of ds */
|
||||
&h_one,
|
||||
d_ds0, /* ds0 is n-by-batchSize */
|
||||
n, /* leading dimension of ds0 */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't cae */
|
||||
d_ds, /* ds is batchSize-by-n */
|
||||
batchSize); /* leading dimension of ds */
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
/* convert dl to interleaved format
|
||||
* dl = transpose(dl0)
|
||||
*/
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
batchSize, /* number of rows of dl */
|
||||
n, /* number of columns of dl */
|
||||
&h_one,
|
||||
d_dl0, /* dl0 is n-by-batchSize */
|
||||
n, /* leading dimension of dl0 */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't cae */
|
||||
d_dl, /* dl is batchSize-by-n */
|
||||
batchSize /* leading dimension of dl */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
|
||||
/* convert d to interleaved format
|
||||
* d = transpose(d0)
|
||||
*/
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
batchSize, /* number of rows of d */
|
||||
n, /* number of columns of d */
|
||||
&h_one,
|
||||
d_d0, /* d0 is n-by-batchSize */
|
||||
n, /* leading dimension of d0 */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't cae */
|
||||
d_d, /* d is batchSize-by-n */
|
||||
batchSize /* leading dimension of d */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
|
||||
/* convert du to interleaved format
|
||||
* du = transpose(du0)
|
||||
*/
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
batchSize, /* number of rows of du */
|
||||
n, /* number of columns of du */
|
||||
&h_one,
|
||||
d_du0, /* du0 is n-by-batchSize */
|
||||
n, /* leading dimension of du0 */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't cae */
|
||||
d_du, /* du is batchSize-by-n */
|
||||
batchSize /* leading dimension of du */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
/* convert dw to interleaved format
|
||||
* dw = transpose(dw0)
|
||||
*/
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
batchSize, /* number of rows of dw */
|
||||
n, /* number of columns of dw */
|
||||
&h_one,
|
||||
d_dw0, /* dw0 is n-by-batchSize */
|
||||
n, /* leading dimension of dw0 */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't cae */
|
||||
d_dw, /* dw is batchSize-by-n */
|
||||
batchSize /* leading dimension of dw */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
|
||||
/* convert B to interleaved format
|
||||
* X = transpose(B)
|
||||
*/
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
batchSize, /* number of rows of X */
|
||||
n, /* number of columns of X */
|
||||
&h_one,
|
||||
d_B, /* B is n-by-batchSize */
|
||||
n, /* leading dimension of B */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't cae */
|
||||
d_X, /* X is batchSize-by-n */
|
||||
batchSize /* leading dimension of X */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
|
||||
/* step 4: prepare workspace */
|
||||
// NOTE: CUDA 10.0
|
||||
// TODO: status = hipsparseSgpsvInterleavedBatch_bufferSizeExt(
|
||||
status = cusparseSgpsvInterleavedBatch_bufferSizeExt(
|
||||
cusparseH,
|
||||
algo,
|
||||
n,
|
||||
d_ds,
|
||||
d_dl,
|
||||
d_d,
|
||||
d_du,
|
||||
d_dw,
|
||||
d_X,
|
||||
batchSize,
|
||||
&lworkInBytes);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
printf("lworkInBytes = %lld \n", (long long)lworkInBytes);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_work, lworkInBytes);
|
||||
cudaStat1 = cudaMalloc((void**)&d_work, lworkInBytes);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
/* step 5: solve Aj*xj = bj */
|
||||
// NOTE: CUDA 10.0
|
||||
// TODO: status = hipsparseSgpsvInterleavedBatch(
|
||||
status = cusparseSgpsvInterleavedBatch(
|
||||
cusparseH,
|
||||
algo,
|
||||
n,
|
||||
d_ds,
|
||||
d_dl,
|
||||
d_d,
|
||||
d_du,
|
||||
d_dw,
|
||||
d_X,
|
||||
batchSize,
|
||||
d_work);
|
||||
// CHECK: cudaStat1 = hipDeviceSynchronize();
|
||||
cudaStat1 = cudaDeviceSynchronize();
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 6: convert X back to aggregate format */
|
||||
/* B = transpose(X) */
|
||||
// CHECK: cublasStat = hipblasSgeam(
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
// CHECK: HIPBLAS_OP_T,
|
||||
cublasStat = cublasSgeam(
|
||||
cublasH,
|
||||
CUBLAS_OP_T, /* transa */
|
||||
CUBLAS_OP_T, /* transb, don't care */
|
||||
n, /* number of rows of B */
|
||||
batchSize, /* number of columns of B */
|
||||
&h_one,
|
||||
d_X, /* X is batchSize-by-n */
|
||||
batchSize, /* leading dimension of X */
|
||||
&h_zero,
|
||||
NULL,
|
||||
n, /* don't cae */
|
||||
d_B, /* B is n-by-batchSize */
|
||||
n /* leading dimension of B */
|
||||
);
|
||||
// CHECK: assert(HIPBLAS_STATUS_SUCCESS == cublasStat);
|
||||
assert(CUBLAS_STATUS_SUCCESS == cublasStat);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
/* step 7: residual evaluation */
|
||||
// CHECK: cudaStat1 = hipMemcpy(X, d_B, sizeof(float)*n*batchSize, hipMemcpyDeviceToHost);
|
||||
cudaStat1 = cudaMemcpy(X, d_B, sizeof(float)*n*batchSize, cudaMemcpyDeviceToHost);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
printf("==== x1 = inv(A1)*b1 \n");
|
||||
for (int j = 0; j < n; j++) {
|
||||
printf("x1[%d] = %f\n", j, X[j]);
|
||||
}
|
||||
|
||||
float r1_nrminf;
|
||||
residaul_eval(
|
||||
n,
|
||||
ds,
|
||||
dl,
|
||||
d,
|
||||
du,
|
||||
dw,
|
||||
B,
|
||||
X,
|
||||
&r1_nrminf
|
||||
);
|
||||
printf("|b1 - A1*x1| = %E\n", r1_nrminf);
|
||||
printf("\n==== x2 = inv(A2)*b2 \n");
|
||||
for (int j = 0; j < n; j++) {
|
||||
printf("x2[%d] = %f\n", j, X[n + j]);
|
||||
}
|
||||
|
||||
float r2_nrminf;
|
||||
residaul_eval(
|
||||
n,
|
||||
ds + n,
|
||||
dl + n,
|
||||
d + n,
|
||||
du + n,
|
||||
dw + n,
|
||||
B + n,
|
||||
X + n,
|
||||
&r2_nrminf
|
||||
);
|
||||
printf("|b2 - A2*x2| = %E\n", r2_nrminf);
|
||||
|
||||
/* free resources */
|
||||
// CHECK: if (d_ds0) hipFree(d_ds0);
|
||||
if (d_ds0) cudaFree(d_ds0);
|
||||
// CHECK: if (d_dl0) hipFree(d_dl0);
|
||||
if (d_dl0) cudaFree(d_dl0);
|
||||
// CHECK: if (d_d0) hipFree(d_d0);
|
||||
if (d_d0) cudaFree(d_d0);
|
||||
// CHECK: if (d_du0) hipFree(d_du0);
|
||||
if (d_du0) cudaFree(d_du0);
|
||||
// CHECK: if (d_dw0) hipFree(d_dw0);
|
||||
if (d_dw0) cudaFree(d_dw0);
|
||||
// CHECK: if (d_ds) hipFree(d_ds);
|
||||
if (d_ds) cudaFree(d_ds);
|
||||
// CHECK: if (d_dl) hipFree(d_dl);
|
||||
if (d_dl) cudaFree(d_dl);
|
||||
// CHECK: if (d_d) hipFree(d_d);
|
||||
if (d_d) cudaFree(d_d);
|
||||
// CHECK: if (d_du) hipFree(d_du);
|
||||
if (d_du) cudaFree(d_du);
|
||||
// CHECK: if (d_dw) hipFree(d_dw);
|
||||
if (d_dw) cudaFree(d_dw);
|
||||
// CHECK: if (d_B) hipFree(d_B);
|
||||
if (d_B) cudaFree(d_B);
|
||||
// CHECK: if (d_X) hipFree(d_X);
|
||||
if (d_X) cudaFree(d_X);
|
||||
// CHECK: if (cusparseH) hipsparseDestroy(cusparseH);
|
||||
if (cusparseH) cusparseDestroy(cusparseH);
|
||||
// CHECK: if (cublasH) hipblasDestroy(cublasH);
|
||||
if (cublasH) cublasDestroy(cublasH);
|
||||
// CHECK: if (stream) hipStreamDestroy(stream);
|
||||
if (stream) cudaStreamDestroy(stream);
|
||||
// CHECK: hipDeviceReset();
|
||||
cudaDeviceReset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,327 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
// CHECK: #include <hipsparse.h>
|
||||
#include <cusparse.h>
|
||||
|
||||
// NOTE: CUDA 10.0
|
||||
|
||||
/* compute | b - A*x|_inf */
|
||||
void residaul_eval(
|
||||
int n,
|
||||
// CHECK: const hipsparseMatDescr_t descrA,
|
||||
const cusparseMatDescr_t descrA,
|
||||
const float *csrVal,
|
||||
const int *csrRowPtr,
|
||||
const int *csrColInd,
|
||||
const float *b,
|
||||
const float *x,
|
||||
float *r_nrminf_ptr)
|
||||
{
|
||||
// CHECK: const int base = (hipsparseGetMatIndexBase(descrA) != HIPSPARSE_INDEX_BASE_ONE) ? 0 : 1;
|
||||
const int base = (cusparseGetMatIndexBase(descrA) != CUSPARSE_INDEX_BASE_ONE) ? 0 : 1;
|
||||
// CHECK: const int lower = (HIPSPARSE_FILL_MODE_LOWER == hipsparseGetMatFillMode(descrA)) ? 1 : 0;
|
||||
const int lower = (CUSPARSE_FILL_MODE_LOWER == cusparseGetMatFillMode(descrA)) ? 1 : 0;
|
||||
// CHECK: const int unit = (HIPSPARSE_DIAG_TYPE_UNIT == hipsparseGetMatDiagType(descrA)) ? 1 : 0;
|
||||
const int unit = (CUSPARSE_DIAG_TYPE_UNIT == cusparseGetMatDiagType(descrA)) ? 1 : 0;
|
||||
|
||||
float r_nrminf = 0;
|
||||
for (int row = 0; row < n; row++) {
|
||||
const int start = csrRowPtr[row] - base;
|
||||
const int end = csrRowPtr[row + 1] - base;
|
||||
float dot = 0;
|
||||
for (int colidx = start; colidx < end; colidx++) {
|
||||
const int col = csrColInd[colidx] - base;
|
||||
float Aij = csrVal[colidx];
|
||||
float xj = x[col];
|
||||
if ((row == col) && unit) {
|
||||
Aij = 1.0;
|
||||
}
|
||||
int valid = (row >= col) && lower ||
|
||||
(row <= col) && !lower;
|
||||
if (valid) {
|
||||
dot += Aij * xj;
|
||||
}
|
||||
}
|
||||
float ri = b[row] - dot;
|
||||
r_nrminf = (r_nrminf > fabs(ri)) ? r_nrminf : fabs(ri);
|
||||
}
|
||||
*r_nrminf_ptr = r_nrminf;
|
||||
}
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
// CHECK: hipsparseHandle_t handle = NULL;
|
||||
cusparseHandle_t handle = NULL;
|
||||
// CHECK: hipStream_t stream = NULL;
|
||||
cudaStream_t stream = NULL;
|
||||
// CHECK: hipsparseMatDescr_t descrA = NULL;
|
||||
cusparseMatDescr_t descrA = NULL;
|
||||
// NOTE: CUDA 10.0
|
||||
// TODO: csrsm2Info_t info = NULL;
|
||||
csrsm2Info_t info = NULL;
|
||||
// CHECK: hipsparseStatus_t status = HIPSPARSE_STATUS_SUCCESS;
|
||||
cusparseStatus_t status = CUSPARSE_STATUS_SUCCESS;
|
||||
// CHECK: hipError_t cudaStat1 = hipSuccess;
|
||||
cudaError_t cudaStat1 = cudaSuccess;
|
||||
const int nrhs = 2;
|
||||
const int n = 4;
|
||||
const int nnzA = 9;
|
||||
// CHECK: const hipsparseSolvePolicy_t policy = HIPSPARSE_SOLVE_POLICY_NO_LEVEL;
|
||||
const cusparseSolvePolicy_t policy = CUSPARSE_SOLVE_POLICY_NO_LEVEL;
|
||||
const float h_one = 1.0;
|
||||
/*
|
||||
* | 1 0 2 -3 |
|
||||
* | 0 4 0 0 |
|
||||
* A = | 5 0 6 7 |
|
||||
* | 0 8 0 9 |
|
||||
*
|
||||
* Regard A as a lower triangle matrix L with non-unit diagonal.
|
||||
* | 1 5 | | 1 5 |
|
||||
* Given B = | 2 6 |, X = L \ B = | 0.5 1.5 |
|
||||
* | 3 7 | | -0.3333 -3 |
|
||||
* | 4 8 | | 0 -0.4444 |
|
||||
*/
|
||||
const int csrRowPtrA[n + 1] = { 1, 4, 5, 8, 10 };
|
||||
const int csrColIndA[nnzA] = { 1, 3, 4, 2, 1, 3, 4, 2, 4 };
|
||||
const float csrValA[nnzA] = { 1, 2, -3, 4, 5, 6, 7, 8, 9 };
|
||||
const float B[n*nrhs] = { 1,2,3,4,5,6,7,8 };
|
||||
float X[n*nrhs];
|
||||
|
||||
int *d_csrRowPtrA = NULL;
|
||||
int *d_csrColIndA = NULL;
|
||||
float *d_csrValA = NULL;
|
||||
float *d_B = NULL;
|
||||
|
||||
size_t lworkInBytes = 0;
|
||||
char *d_work = NULL;
|
||||
|
||||
const int algo = 0; /* non-block version */
|
||||
|
||||
printf("example of csrsm2 \n");
|
||||
|
||||
/* step 1: create cusparse handle, bind a stream */
|
||||
// CHECK: cudaStat1 = hipStreamCreateWithFlags(&stream, hipStreamNonBlocking);
|
||||
cudaStat1 = cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: status = hipsparseCreate(&handle);
|
||||
status = cusparseCreate(&handle);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
status = cusparseSetStream(handle, stream);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
// NOTE: CUDA 10.0
|
||||
// TODO: status = hipsparseCreateCsrsm2Info(&info);
|
||||
status = cusparseCreateCsrsm2Info(&info);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
/* step 2: configuration of matrix A */
|
||||
status = cusparseCreateMatDescr(&descrA);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
/* A is base-1*/
|
||||
// CHECK: hipsparseSetMatIndexBase(descrA, HIPSPARSE_INDEX_BASE_ONE);
|
||||
cusparseSetMatIndexBase(descrA, CUSPARSE_INDEX_BASE_ONE);
|
||||
// CHECK: hipsparseSetMatType(descrA, HIPSPARSE_MATRIX_TYPE_GENERAL);
|
||||
cusparseSetMatType(descrA, CUSPARSE_MATRIX_TYPE_GENERAL);
|
||||
/* A is lower triangle */
|
||||
// CHECK: hipsparseSetMatFillMode(descrA, HIPSPARSE_FILL_MODE_LOWER);
|
||||
cusparseSetMatFillMode(descrA, CUSPARSE_FILL_MODE_LOWER);
|
||||
/* A has non unit diagonal */
|
||||
// CHECK: hipsparseSetMatDiagType(descrA, HIPSPARSE_DIAG_TYPE_NON_UNIT);
|
||||
cusparseSetMatDiagType(descrA, CUSPARSE_DIAG_TYPE_NON_UNIT);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrRowPtrA, sizeof(int)*(n + 1));
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrRowPtrA, sizeof(int)*(n + 1));
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrColIndA, sizeof(int)*nnzA);
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrColIndA, sizeof(int)*nnzA);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_csrValA, sizeof(float)*nnzA);
|
||||
cudaStat1 = cudaMalloc((void**)&d_csrValA, sizeof(float)*nnzA);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_B, sizeof(float)*n*nrhs);
|
||||
cudaStat1 = cudaMalloc((void**)&d_B, sizeof(float)*n*nrhs);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_csrRowPtrA, csrRowPtrA, sizeof(int)*(n + 1), hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_csrRowPtrA, csrRowPtrA, sizeof(int)*(n + 1), cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_csrColIndA, csrColIndA, sizeof(int)*nnzA, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_csrColIndA, csrColIndA, sizeof(int)*nnzA, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_csrValA, csrValA, sizeof(float)*nnzA, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_csrValA, csrValA, sizeof(float)*nnzA, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: cudaStat1 = hipMemcpy(d_B, B, sizeof(float)*n*nrhs, hipMemcpyHostToDevice);
|
||||
cudaStat1 = cudaMemcpy(d_B, B, sizeof(float)*n*nrhs, cudaMemcpyHostToDevice);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 3: query workspace */
|
||||
// NOTE: CUDA 10.0
|
||||
// TODO: status = hipsparseScsrsm2_bufferSizeExt(
|
||||
// CHECK: HIPSPARSE_OPERATION_NON_TRANSPOSE,
|
||||
// CHECK: HIPSPARSE_OPERATION_NON_TRANSPOSE,
|
||||
status = cusparseScsrsm2_bufferSizeExt(
|
||||
handle,
|
||||
algo,
|
||||
CUSPARSE_OPERATION_NON_TRANSPOSE, /* transA */
|
||||
CUSPARSE_OPERATION_NON_TRANSPOSE, /* transB */
|
||||
n,
|
||||
nrhs,
|
||||
nnzA,
|
||||
&h_one,
|
||||
descrA,
|
||||
d_csrValA,
|
||||
d_csrRowPtrA,
|
||||
d_csrColIndA,
|
||||
d_B,
|
||||
n, /* ldb */
|
||||
info,
|
||||
policy,
|
||||
&lworkInBytes);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
|
||||
printf("lworkInBytes = %lld \n", (long long)lworkInBytes);
|
||||
// CHECK: if (NULL != d_work) { hipFree(d_work); }
|
||||
if (NULL != d_work) { cudaFree(d_work); }
|
||||
// CHECK: cudaStat1 = hipMalloc((void**)&d_work, lworkInBytes);
|
||||
cudaStat1 = cudaMalloc((void**)&d_work, lworkInBytes);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 4: analysis */
|
||||
// NOTE: CUDA 10.0
|
||||
// TODO: status = hipsparseScsrsm2_analysis(
|
||||
// CHECK: HIPSPARSE_OPERATION_NON_TRANSPOSE,
|
||||
// CHECK: HIPSPARSE_OPERATION_NON_TRANSPOSE,
|
||||
status = cusparseScsrsm2_analysis(
|
||||
handle,
|
||||
algo,
|
||||
CUSPARSE_OPERATION_NON_TRANSPOSE, /* transA */
|
||||
CUSPARSE_OPERATION_NON_TRANSPOSE, /* transB */
|
||||
n,
|
||||
nrhs,
|
||||
nnzA,
|
||||
&h_one,
|
||||
descrA,
|
||||
d_csrValA,
|
||||
d_csrRowPtrA,
|
||||
d_csrColIndA,
|
||||
d_B,
|
||||
n, /* ldb */
|
||||
info,
|
||||
policy,
|
||||
d_work);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
/* step 5: solve L * X = B */
|
||||
// NOTE: CUDA 10.0
|
||||
// TODO: status = hipsparseScsrsm2_solve(
|
||||
// CHECK: HIPSPARSE_OPERATION_NON_TRANSPOSE,
|
||||
// CHECK: HIPSPARSE_OPERATION_NON_TRANSPOSE,
|
||||
status = cusparseScsrsm2_solve(
|
||||
handle,
|
||||
algo,
|
||||
CUSPARSE_OPERATION_NON_TRANSPOSE, /* transA */
|
||||
CUSPARSE_OPERATION_NON_TRANSPOSE, /* transB */
|
||||
n,
|
||||
nrhs,
|
||||
nnzA,
|
||||
&h_one,
|
||||
descrA,
|
||||
d_csrValA,
|
||||
d_csrRowPtrA,
|
||||
d_csrColIndA,
|
||||
d_B,
|
||||
n, /* ldb */
|
||||
info,
|
||||
policy,
|
||||
d_work);
|
||||
// CHECK: assert(HIPSPARSE_STATUS_SUCCESS == status);
|
||||
assert(CUSPARSE_STATUS_SUCCESS == status);
|
||||
// CHECK: cudaStat1 = hipDeviceSynchronize();
|
||||
cudaStat1 = cudaDeviceSynchronize();
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
|
||||
/* step 6:measure residual B - A*X */
|
||||
// CHECK: cudaStat1 = hipMemcpy(X, d_B, sizeof(float)*n*nrhs, hipMemcpyDeviceToHost);
|
||||
cudaStat1 = cudaMemcpy(X, d_B, sizeof(float)*n*nrhs, cudaMemcpyDeviceToHost);
|
||||
// CHECK: assert(hipSuccess == cudaStat1);
|
||||
assert(cudaSuccess == cudaStat1);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
printf("==== x1 = inv(A)*b1 \n");
|
||||
for (int j = 0; j < n; j++) {
|
||||
printf("x1[%d] = %f\n", j, X[j]);
|
||||
}
|
||||
float r1_nrminf;
|
||||
residaul_eval(
|
||||
n,
|
||||
descrA,
|
||||
csrValA,
|
||||
csrRowPtrA,
|
||||
csrColIndA,
|
||||
B,
|
||||
X,
|
||||
&r1_nrminf
|
||||
);
|
||||
printf("|b1 - A*x1| = %E\n", r1_nrminf);
|
||||
|
||||
printf("==== x2 = inv(A)*b2 \n");
|
||||
for (int j = 0; j < n; j++) {
|
||||
printf("x2[%d] = %f\n", j, X[n + j]);
|
||||
}
|
||||
float r2_nrminf;
|
||||
residaul_eval(
|
||||
n,
|
||||
descrA,
|
||||
csrValA,
|
||||
csrRowPtrA,
|
||||
csrColIndA,
|
||||
B + n,
|
||||
X + n,
|
||||
&r2_nrminf
|
||||
);
|
||||
printf("|b2 - A*x2| = %E\n", r2_nrminf);
|
||||
|
||||
/* free resources */
|
||||
// CHECK: if (d_csrRowPtrA) hipFree(d_csrRowPtrA);
|
||||
if (d_csrRowPtrA) cudaFree(d_csrRowPtrA);
|
||||
// CHECK: if (d_csrColIndA) hipFree(d_csrColIndA);
|
||||
if (d_csrColIndA) cudaFree(d_csrColIndA);
|
||||
// CHECK: if (d_csrValA) hipFree(d_csrValA);
|
||||
if (d_csrValA) cudaFree(d_csrValA);
|
||||
// CHECK: if (d_B) hipFree(d_B);
|
||||
if (d_B) cudaFree(d_B);
|
||||
// CHECK: if (handle) hipsparseDestroy(handle);
|
||||
if (handle) cusparseDestroy(handle);
|
||||
// CHECK: if (stream) hipStreamDestroy(stream);
|
||||
if (stream) cudaStreamDestroy(stream);
|
||||
// CHECK: if (descrA) hipsparseDestroyMatDescr(descrA);
|
||||
if (descrA) cusparseDestroyMatDescr(descrA);
|
||||
// NOTE: CUDA 10.0
|
||||
// TODO: if (info) hipsparseDestroyCsrsm2Info(info);
|
||||
if (info) cusparseDestroyCsrsm2Info(info);
|
||||
// CHECK: hipDeviceReset();
|
||||
cudaDeviceReset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,410 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
// CHECK: #include <hipsparse.h>
|
||||
// CHECK: #include <hipblas.h>
|
||||
#include <cuda.h>
|
||||
#include <cusparse_v2.h>
|
||||
#include <cublas_v2.h>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
|
||||
#define Min(x,y) ((x)<(y)?(x):(y))
|
||||
#define Max(x,y) ((x)>(y)?(x):(y))
|
||||
#define Abs(x) ((x)>(0)?(x):-(x))
|
||||
// CHECK: static void CudaCheckCore(hipError_t code, const char *file, int line) {
|
||||
static void CudaCheckCore(cudaError_t code, const char *file, int line) {
|
||||
// CHECK: if (code != hipSuccess) {
|
||||
if (code != cudaSuccess) {
|
||||
// CHECK: fprintf(stderr,"Cuda Error %d : %s %s %d\n", code, hipGetErrorString(code), file, line);
|
||||
fprintf(stderr,"Cuda Error %d : %s %s %d\n", code, cudaGetErrorString(code), file, line);
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
#define CudaCheck( test ) { CudaCheckCore((test), __FILE__, __LINE__); }
|
||||
// CHECK: #define CudaCheckAfterCall() { CudaCheckCore((hipGetLastError()), __FILE__, __LINE__); }
|
||||
#define CudaCheckAfterCall() { CudaCheckCore((cudaGetLastError()), __FILE__, __LINE__); }
|
||||
|
||||
// CHECK: static const char * GetErrorString(hipsparseStatus_t error) {
|
||||
static const char * GetErrorString(cusparseStatus_t error) {
|
||||
switch (error) {
|
||||
// CHECK: case HIPSPARSE_STATUS_SUCCESS:
|
||||
case CUSPARSE_STATUS_SUCCESS:
|
||||
return "The operation completed successfully.";
|
||||
// CHECK: case HIPSPARSE_STATUS_NOT_INITIALIZED:
|
||||
case CUSPARSE_STATUS_NOT_INITIALIZED:
|
||||
return "The cuSPARSE library was not initialized. This is usually caused by the lack of a prior call, an error in the CUDA Runtime API called by the cuSPARSE routine, or an error in the hardware setup.\n" \
|
||||
"To correct: call cusparseCreate() prior to the function call; and check that the hardware, an appropriate version of the driver, and the cuSPARSE library are correctly installed.";
|
||||
// CHECK: case HIPSPARSE_STATUS_ALLOC_FAILED:
|
||||
case CUSPARSE_STATUS_ALLOC_FAILED:
|
||||
return "Resource allocation failed inside the cuSPARSE library. This is usually caused by a cudaMalloc() failure.\n"\
|
||||
"To correct: prior to the function call, deallocate previously allocated memory as much as possible.";
|
||||
// CHECK: case HIPSPARSE_STATUS_INVALID_VALUE:
|
||||
case CUSPARSE_STATUS_INVALID_VALUE:
|
||||
return "An unsupported value or parameter was passed to the function (a negative vector size, for example).\n"\
|
||||
"To correct: ensure that all the parameters being passed have valid values.";
|
||||
// CHECK: case HIPSPARSE_STATUS_ARCH_MISMATCH:
|
||||
case CUSPARSE_STATUS_ARCH_MISMATCH:
|
||||
return "The function requires a feature absent from the device architecture; usually caused by the lack of support for atomic operations or double precision.\n"\
|
||||
"To correct: compile and run the application on a device with appropriate compute capability, which is 1.1 for 32-bit atomic operations and 1.3 for double precision.";
|
||||
// CHECK: case HIPSPARSE_STATUS_MAPPING_ERROR:
|
||||
case CUSPARSE_STATUS_MAPPING_ERROR:
|
||||
return "An access to GPU memory space failed, which is usually caused by a failure to bind a texture.\n"\
|
||||
"To correct: prior to the function call, unbind any previously bound textures.";
|
||||
// CHECK: case HIPSPARSE_STATUS_EXECUTION_FAILED:
|
||||
case CUSPARSE_STATUS_EXECUTION_FAILED:
|
||||
return "The GPU program failed to execute. This is often caused by a launch failure of the kernel on the GPU, which can be caused by multiple reasons.\n"\
|
||||
"To correct: check that the hardware, an appropriate version of the driver, and the cuSPARSE library are correctly installed.";
|
||||
// CHECK: case HIPSPARSE_STATUS_INTERNAL_ERROR:
|
||||
case CUSPARSE_STATUS_INTERNAL_ERROR:
|
||||
return "An internal cuSPARSE operation failed. This error is usually caused by a cudaMemcpyAsync() failure.\n"\
|
||||
"To correct: check that the hardware, an appropriate version of the driver, and the cuSPARSE library are correctly installed. Also, check that the memory passed as a parameter to the routine is not being deallocated prior to the routine’s completion.";
|
||||
// CHECK: case HIPSPARSE_STATUS_MATRIX_TYPE_NOT_SUPPORTED:
|
||||
// CHECK: "To correct: check that the fields in hipsparseMatDescr_t descrA were set correctly.";
|
||||
case CUSPARSE_STATUS_MATRIX_TYPE_NOT_SUPPORTED:
|
||||
return "The matrix type is not supported by this function. This is usually caused by passing an invalid matrix descriptor to the function.\n"\
|
||||
"To correct: check that the fields in cusparseMatDescr_t descrA were set correctly.";
|
||||
}
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
// CHECK: static void CudaSparseCheckCore(hipsparseStatus_t code, const char *file, int line) {
|
||||
static void CudaSparseCheckCore(cusparseStatus_t code, const char *file, int line) {
|
||||
// CHECK: if (code != HIPSPARSE_STATUS_SUCCESS) {
|
||||
if (code != CUSPARSE_STATUS_SUCCESS) {
|
||||
fprintf(stderr,"Cuda Error %d : %s %s %d\n", code, GetErrorString(code), file, line);
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
#define CudaSparseCheck( test ) { CudaSparseCheckCore((test), __FILE__, __LINE__); }
|
||||
|
||||
// Alloc and copy
|
||||
template <class ObjectType>
|
||||
ObjectType* allocAndCopy(const ObjectType src[], const int size) {
|
||||
ObjectType* dest = NULL;
|
||||
// CHECK: CudaCheck( hipMalloc(&dest,size*sizeof(ObjectType)) );
|
||||
CudaCheck( cudaMalloc(&dest,size*sizeof(ObjectType)) );
|
||||
// CHECK: CudaCheck( hipMemcpy(dest, src, size*sizeof(ObjectType), hipMemcpyHostToDevice ) );
|
||||
CudaCheck( cudaMemcpy(dest, src, size*sizeof(ObjectType), cudaMemcpyHostToDevice ) );
|
||||
return dest;
|
||||
}
|
||||
|
||||
template <class ObjectType>
|
||||
ObjectType* alloc(const int size) {
|
||||
ObjectType* dest = NULL;
|
||||
// CHECK: CudaCheck( hipMalloc(&dest,size*sizeof(ObjectType)) );
|
||||
CudaCheck( cudaMalloc(&dest,size*sizeof(ObjectType)) );
|
||||
return dest;
|
||||
}
|
||||
|
||||
template <class ObjectType>
|
||||
ObjectType* allocAndCopyPart(const ObjectType src[], const int size, const int allocSize) {
|
||||
ObjectType* dest = NULL;
|
||||
assert(size <= allocSize);
|
||||
// CHECK: CudaCheck( hipMalloc(&dest,allocSize*sizeof(ObjectType)) );
|
||||
// CHECK: CudaCheck( hipMemcpy(dest, src, size*sizeof(ObjectType), hipMemcpyHostToDevice ) );
|
||||
// CHECK: CudaCheck( hipMemset(&dest[size],0,(allocSize-size)*sizeof(ObjectType)) );
|
||||
CudaCheck( cudaMalloc(&dest,allocSize*sizeof(ObjectType)) );
|
||||
CudaCheck( cudaMemcpy(dest, src, size*sizeof(ObjectType), cudaMemcpyHostToDevice ) );
|
||||
CudaCheck( cudaMemset(&dest[size],0,(allocSize-size)*sizeof(ObjectType)) );
|
||||
return dest;
|
||||
}
|
||||
|
||||
// COO part
|
||||
#include <algorithm>
|
||||
|
||||
struct Ijv {
|
||||
int i, j;
|
||||
double v;
|
||||
};
|
||||
|
||||
bool IjvComp(const Ijv& v1, const Ijv& v2) {
|
||||
return v1.i < v2.i || (v1.i == v2.i && v1.j < v2.j);
|
||||
}
|
||||
|
||||
struct COOArrays {
|
||||
int m;
|
||||
int nnz;
|
||||
double *val;/*values(NNZ)*/
|
||||
int *rowind;/*i(NNZ)*/
|
||||
int *colind;/*j(NNZ)*/
|
||||
|
||||
COOArrays() {
|
||||
val = NULL;
|
||||
rowind = NULL;
|
||||
colind = NULL;
|
||||
}
|
||||
|
||||
~COOArrays() {
|
||||
delete[] val;
|
||||
delete[] rowind;
|
||||
delete[] colind;
|
||||
}
|
||||
|
||||
void sortToRowMajor() {
|
||||
Ijv* ijvs = new Ijv[nnz];
|
||||
for(int idxCopy = 0 ; idxCopy < nnz ; ++idxCopy){
|
||||
ijvs[idxCopy].i = rowind[idxCopy];
|
||||
ijvs[idxCopy].j = colind[idxCopy];
|
||||
ijvs[idxCopy].v = val[idxCopy];
|
||||
}
|
||||
std::sort(ijvs, ijvs+nnz, IjvComp);
|
||||
for(int idxCopy = 0 ; idxCopy < nnz ; ++idxCopy){
|
||||
rowind[idxCopy] = ijvs[idxCopy].i;
|
||||
colind[idxCopy] = ijvs[idxCopy].j;
|
||||
val[idxCopy] = ijvs[idxCopy].v;
|
||||
}
|
||||
delete[] ijvs;
|
||||
}
|
||||
};
|
||||
|
||||
void compute_COO(COOArrays& coo, double *x , double *y ) {
|
||||
for(int idxVal = 0 ; idxVal < coo.nnz ; ++idxVal){
|
||||
y[coo.rowind[idxVal]] += x[coo.colind[idxVal]] * coo.val[idxVal];
|
||||
}
|
||||
}
|
||||
|
||||
// COO part
|
||||
struct CRSArrays {
|
||||
int m; //< the dim of the matrix
|
||||
int nnz;//< the number of nnz (== ia[m])
|
||||
double *cu_csrValA; //< the values (of size NNZ)
|
||||
int *cu_csrRowPtrA;//< the usual rowptr (of size m+1)
|
||||
int *cu_csrColIndA;//< the colidx of each NNZ (of size nnz)
|
||||
// CHECK: hipStream_t streamId;
|
||||
// CHECK: hipsparseHandle_t cusparseHandle;
|
||||
cudaStream_t streamId;
|
||||
cusparseHandle_t cusparseHandle;
|
||||
|
||||
CRSArrays() {
|
||||
cu_csrValA = NULL;
|
||||
cu_csrRowPtrA = NULL;
|
||||
cu_csrColIndA = NULL;
|
||||
// Create sparse handle (needed to call sparse functions
|
||||
streamId = 0;
|
||||
// CHECK-NOT: hipsparseHandle = 0;
|
||||
cusparseHandle = 0;
|
||||
// CHECK: CudaSparseCheck(hipsparseCreate(&cusparseHandle));
|
||||
// CHECK: CudaSparseCheck(hipsparseSetStream(cusparseHandle, streamId));
|
||||
CudaSparseCheck(cusparseCreate(&cusparseHandle));
|
||||
CudaSparseCheck(cusparseSetStream(cusparseHandle, streamId));
|
||||
}
|
||||
|
||||
~CRSArrays() {
|
||||
// CHECK: CudaCheck(hipFree(cu_csrValA));
|
||||
// CHECK: CudaCheck(hipFree(cu_csrRowPtrA));
|
||||
// CHECK: CudaCheck(hipFree(cu_csrColIndA));
|
||||
CudaCheck(cudaFree(cu_csrValA));
|
||||
CudaCheck(cudaFree(cu_csrRowPtrA));
|
||||
CudaCheck(cudaFree(cu_csrColIndA));
|
||||
// Destroy sparse handle
|
||||
// CHECK: CudaSparseCheck(hipsparseDestroy(cusparseHandle));
|
||||
CudaSparseCheck(cusparseDestroy(cusparseHandle));
|
||||
}
|
||||
};
|
||||
|
||||
void COO_to_CRS(COOArrays& coo, CRSArrays* crs) {
|
||||
// We need COO to be sorted by row (and column)
|
||||
coo.sortToRowMajor();
|
||||
crs->m = coo.m;
|
||||
crs->nnz = coo.nnz;
|
||||
// Convert COO to CSR (it is just for the rows idx)
|
||||
crs->cu_csrRowPtrA = alloc<int>(coo.m+1);
|
||||
{
|
||||
int* cu_cooRowIndA = allocAndCopy(coo.rowind, coo.nnz);
|
||||
// CHECK: CudaSparseCheck(hipsparseXcoo2csr(crs->cusparseHandle, cu_cooRowIndA,
|
||||
// CHECK: coo.nnz, coo.m, crs->cu_csrRowPtrA, HIPSPARSE_INDEX_BASE_ZERO));
|
||||
CudaSparseCheck(cusparseXcoo2csr(crs->cusparseHandle, cu_cooRowIndA,
|
||||
coo.nnz, coo.m, crs->cu_csrRowPtrA, CUSPARSE_INDEX_BASE_ZERO));
|
||||
// CHECK: CudaCheck(hipFree(cu_cooRowIndA));
|
||||
CudaCheck(cudaFree(cu_cooRowIndA));
|
||||
}
|
||||
// Copy cols idx and values that are unchanged
|
||||
crs->cu_csrValA = allocAndCopy(coo.val, coo.nnz);
|
||||
crs->cu_csrColIndA = allocAndCopy(coo.colind, coo.nnz);
|
||||
}
|
||||
|
||||
double compute_CRS( CRSArrays& crs, double *x , double *y) {
|
||||
// For blas 2 gemv y = alpha.x.A + Beta.y
|
||||
const double alpha = 1.0;
|
||||
const double beta = 0.0;
|
||||
// Copy input
|
||||
double* cu_x = allocAndCopy(x, crs.m);
|
||||
double* cu_y = allocAndCopy(y, crs.m);
|
||||
// Init matrix properties
|
||||
// CHECK: hipsparseMatDescr_t descr = 0;
|
||||
cusparseMatDescr_t descr = 0;
|
||||
// CHECK: CudaSparseCheck(hipsparseCreateMatDescr(&descr));
|
||||
CudaSparseCheck(cusparseCreateMatDescr(&descr));
|
||||
// CHECK: hipsparseSetMatType(descr,HIPSPARSE_MATRIX_TYPE_GENERAL);
|
||||
cusparseSetMatType(descr,CUSPARSE_MATRIX_TYPE_GENERAL);
|
||||
// CHECK: hipsparseSetMatIndexBase(descr,HIPSPARSE_INDEX_BASE_ZERO);
|
||||
cusparseSetMatIndexBase(descr,CUSPARSE_INDEX_BASE_ZERO);
|
||||
// Compute gemv
|
||||
float gemvComputeTume = 0;
|
||||
{
|
||||
// CHECK: hipEvent_t startTime, stopTime;
|
||||
// CHECK: hipEventCreate(&startTime);
|
||||
// CHECK: hipEventCreate(&stopTime);
|
||||
// CHECK: hipEventRecord(startTime, crs.streamId);
|
||||
cudaEvent_t startTime, stopTime;
|
||||
cudaEventCreate(&startTime);
|
||||
cudaEventCreate(&stopTime);
|
||||
cudaEventRecord(startTime, crs.streamId);
|
||||
// CHECK: CudaSparseCheck(hipsparseDcsrmv(crs.cusparseHandle, HIPSPARSE_OPERATION_NON_TRANSPOSE,
|
||||
CudaSparseCheck(cusparseDcsrmv(crs.cusparseHandle, CUSPARSE_OPERATION_NON_TRANSPOSE,
|
||||
crs.m, crs.m, crs.nnz, &alpha,
|
||||
descr, crs.cu_csrValA, crs.cu_csrRowPtrA,
|
||||
crs.cu_csrColIndA, cu_x, &beta, cu_y));
|
||||
// CHECK: hipEventRecord(stopTime, crs.streamId);
|
||||
// CHECK: hipEventSynchronize(stopTime);
|
||||
// CHECK: hipEventElapsedTime(&gemvComputeTume, startTime, stopTime);
|
||||
cudaEventRecord(stopTime, crs.streamId);
|
||||
cudaEventSynchronize(stopTime);
|
||||
cudaEventElapsedTime(&gemvComputeTume, startTime, stopTime);
|
||||
gemvComputeTume /=1000.0;
|
||||
}
|
||||
// Get back result
|
||||
// CHECK: CudaCheck( hipMemcpy(y, cu_y, crs.m*sizeof(double), hipMemcpyDeviceToHost ) );
|
||||
CudaCheck( cudaMemcpy(y, cu_y, crs.m*sizeof(double), cudaMemcpyDeviceToHost ) );
|
||||
// Dealloc vectors
|
||||
// CHECK: CudaCheck(hipFree(cu_x));
|
||||
// CHECK: CudaCheck(hipFree(cu_y));
|
||||
CudaCheck(cudaFree(cu_x));
|
||||
CudaCheck(cudaFree(cu_y));
|
||||
return gemvComputeTume;
|
||||
}
|
||||
|
||||
// BCSR part
|
||||
struct BCRSArrays {
|
||||
int m;
|
||||
int nnz;
|
||||
int nbBlocks;
|
||||
int nbBlockRow;
|
||||
int blockSize;
|
||||
int* cu_bsrRowPtrC;
|
||||
int* cu_bsrColIndC;
|
||||
double* cu_bsrValC;
|
||||
// CHECK: hipStream_t streamId;
|
||||
cudaStream_t streamId;
|
||||
// CHECK: hipsparseHandle_t cusparseHandle;
|
||||
cusparseHandle_t cusparseHandle;
|
||||
|
||||
BCRSArrays() {
|
||||
cu_bsrRowPtrC = NULL;
|
||||
cu_bsrColIndC = NULL;
|
||||
cu_bsrValC = NULL;
|
||||
// Create sparse handle (needed to call sparse functions
|
||||
streamId = 0;
|
||||
// CHECK: CudaSparseCheck(hipsparseCreate(&cusparseHandle));
|
||||
// CHECK: CudaSparseCheck(hipsparseSetStream(cusparseHandle, streamId));
|
||||
CudaSparseCheck(cusparseCreate(&cusparseHandle));
|
||||
CudaSparseCheck(cusparseSetStream(cusparseHandle, streamId));
|
||||
}
|
||||
|
||||
~BCRSArrays() {
|
||||
// CHECK: CudaCheck(hipFree(cu_bsrRowPtrC));
|
||||
// CHECK: CudaCheck(hipFree(cu_bsrColIndC));
|
||||
// CHECK: CudaCheck(hipFree(cu_bsrValC));
|
||||
CudaCheck(cudaFree(cu_bsrRowPtrC));
|
||||
CudaCheck(cudaFree(cu_bsrColIndC));
|
||||
CudaCheck(cudaFree(cu_bsrValC));
|
||||
// Destroy sparse handle
|
||||
// CHECK: CudaSparseCheck(hipsparseDestroy(cusparseHandle));
|
||||
CudaSparseCheck(cusparseDestroy(cusparseHandle));
|
||||
}
|
||||
};
|
||||
|
||||
void CRS_to_BCRS(CRSArrays& csr, BCRSArrays* bcrs, const int blockSize) {
|
||||
bcrs->m = csr.m;
|
||||
bcrs->nnz = csr.nnz;
|
||||
bcrs->blockSize = blockSize;
|
||||
bcrs->nbBlockRow = (csr.m + blockSize-1)/blockSize;
|
||||
// CHECK: hipMalloc((void**)&bcrs->cu_bsrRowPtrC, sizeof(int) *(bcrs->nbBlockRow+1));
|
||||
cudaMalloc((void**)&bcrs->cu_bsrRowPtrC, sizeof(int) *(bcrs->nbBlockRow+1));
|
||||
// CHECK: hipsparseMatDescr_t descr = 0;
|
||||
cusparseMatDescr_t descr = 0;
|
||||
// CHECK: CudaSparseCheck(hipsparseCreateMatDescr(&descr));
|
||||
// CHECK: hipsparseSetMatType(descr,HIPSPARSE_MATRIX_TYPE_GENERAL);
|
||||
// CHECK: hipsparseSetMatIndexBase(descr,HIPSPARSE_INDEX_BASE_ZERO);
|
||||
CudaSparseCheck(cusparseCreateMatDescr(&descr));
|
||||
cusparseSetMatType(descr,CUSPARSE_MATRIX_TYPE_GENERAL);
|
||||
cusparseSetMatIndexBase(descr,CUSPARSE_INDEX_BASE_ZERO);
|
||||
int nbNnzBlocks;
|
||||
// NOTE: cusparseXcsr2bsrNnz and CUSPARSE_DIRECTION_COLUMN (of type cusparseDirection_t) are yet unsupported by HIP
|
||||
// CHECK-NOT: hipsparseXcsr2bsrNnz(bcrs->cusparseHandle, HIPSPARSE_DIRECTION_COLUMN, csr.m, csr.m, descr, csr.cu_csrRowPtrA, csr.cu_csrColIndA,
|
||||
cusparseXcsr2bsrNnz(bcrs->cusparseHandle, CUSPARSE_DIRECTION_COLUMN, csr.m, csr.m, descr, csr.cu_csrRowPtrA, csr.cu_csrColIndA,
|
||||
blockSize, descr, bcrs->cu_bsrRowPtrC, &nbNnzBlocks);
|
||||
{
|
||||
int firstBlockIdx, lastBlockIdx;
|
||||
// CHECK: hipMemcpy(&lastBlockIdx, bcrs->cu_bsrRowPtrC+bcrs->nbBlockRow, sizeof(int), hipMemcpyDeviceToHost);
|
||||
// CHECK: hipMemcpy(&firstBlockIdx, bcrs->cu_bsrRowPtrC, sizeof(int), hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(&lastBlockIdx, bcrs->cu_bsrRowPtrC+bcrs->nbBlockRow, sizeof(int), cudaMemcpyDeviceToHost);
|
||||
cudaMemcpy(&firstBlockIdx, bcrs->cu_bsrRowPtrC, sizeof(int), cudaMemcpyDeviceToHost);
|
||||
assert(firstBlockIdx == 0); // we are in base 0
|
||||
assert(nbNnzBlocks == lastBlockIdx - firstBlockIdx);
|
||||
}
|
||||
bcrs->nbBlocks = nbNnzBlocks;
|
||||
// CHECK: CudaCheck(hipMalloc((void**)&bcrs->cu_bsrColIndC, sizeof(int)*nbNnzBlocks));
|
||||
// CHECK: CudaCheck(hipMalloc((void**)&bcrs->cu_bsrValC, sizeof(double)*(blockSize*blockSize)*nbNnzBlocks));
|
||||
CudaCheck(cudaMalloc((void**)&bcrs->cu_bsrColIndC, sizeof(int)*nbNnzBlocks));
|
||||
CudaCheck(cudaMalloc((void**)&bcrs->cu_bsrValC, sizeof(double)*(blockSize*blockSize)*nbNnzBlocks));
|
||||
// NOTE: cusparseDcsr2bsr and CUSPARSE_DIRECTION_COLUMN (of type cusparseDirection_t) are yet unsupported by HIP
|
||||
// CHECK-NOT: hipsparseDcsr2bsr(bcrs->cusparseHandle, HIPSPARSE_DIRECTION_COLUMN,
|
||||
cusparseDcsr2bsr(bcrs->cusparseHandle, CUSPARSE_DIRECTION_COLUMN,
|
||||
csr.m, csr.m, descr, csr.cu_csrValA, csr.cu_csrRowPtrA, csr.cu_csrColIndA, blockSize, descr, bcrs->cu_bsrValC, bcrs->cu_bsrRowPtrC, bcrs->cu_bsrColIndC);
|
||||
}
|
||||
|
||||
double compute_BSR(BCRSArrays& bcsr, double *x , double *y){
|
||||
// For blas 2 gemv y = alpha.x.A + Beta.y
|
||||
const double alpha = 1.0;
|
||||
const double beta = 0.0;
|
||||
// Copy input
|
||||
const int sizeMultipleBlockSize = ((bcsr.m+bcsr.blockSize-1)/bcsr.blockSize)*bcsr.blockSize;
|
||||
double* cu_x = allocAndCopyPart(x, bcsr.m, sizeMultipleBlockSize);
|
||||
double* cu_y = allocAndCopyPart(y, bcsr.m, sizeMultipleBlockSize);
|
||||
// Init matrix properties
|
||||
// CHECK: hipsparseMatDescr_t descr = 0;
|
||||
// CHECK: CudaSparseCheck(hipsparseCreateMatDescr(&descr));
|
||||
// CHECK: hipsparseSetMatType(descr,HIPSPARSE_MATRIX_TYPE_GENERAL);
|
||||
// CHECK: hipsparseSetMatIndexBase(descr,HIPSPARSE_INDEX_BASE_ZERO);
|
||||
cusparseMatDescr_t descr = 0;
|
||||
CudaSparseCheck(cusparseCreateMatDescr(&descr));
|
||||
cusparseSetMatType(descr,CUSPARSE_MATRIX_TYPE_GENERAL);
|
||||
cusparseSetMatIndexBase(descr,CUSPARSE_INDEX_BASE_ZERO);
|
||||
// Compute gemv
|
||||
float gemvComputeTume = 0;
|
||||
{
|
||||
// CHECK: hipEvent_t startTime, stopTime;
|
||||
// CHECK: hipEventCreate(&startTime);
|
||||
// CHECK: hipEventCreate(&stopTime);
|
||||
// CHECK: hipEventRecord(startTime, bcsr.streamId);
|
||||
cudaEvent_t startTime, stopTime;
|
||||
cudaEventCreate(&startTime);
|
||||
cudaEventCreate(&stopTime);
|
||||
cudaEventRecord(startTime, bcsr.streamId);
|
||||
// CHECK: cusparseDbsrmv(bcsr.cusparseHandle, HIPSPARSE_DIRECTION_COLUMN, HIPSPARSE_OPERATION_NON_TRANSPOSE,
|
||||
cusparseDbsrmv(bcsr.cusparseHandle, CUSPARSE_DIRECTION_COLUMN, CUSPARSE_OPERATION_NON_TRANSPOSE,
|
||||
bcsr.nbBlockRow, bcsr.m, bcsr.nbBlocks, &alpha, descr,
|
||||
bcsr.cu_bsrValC, bcsr.cu_bsrRowPtrC, bcsr.cu_bsrColIndC, bcsr.blockSize,
|
||||
cu_x, &beta, cu_y);
|
||||
// CHECK: hipEventRecord(stopTime, bcsr.streamId);
|
||||
// CHECK: hipEventSynchronize(stopTime);
|
||||
// CHECK: hipEventElapsedTime(&gemvComputeTume, startTime, stopTime);
|
||||
cudaEventRecord(stopTime, bcsr.streamId);
|
||||
cudaEventSynchronize(stopTime);
|
||||
cudaEventElapsedTime(&gemvComputeTume, startTime, stopTime);
|
||||
gemvComputeTume /=1000.0;
|
||||
}
|
||||
// Get back result
|
||||
// CHECK: CudaCheck( hipMemcpy(y, cu_y, bcsr.m*sizeof(double), hipMemcpyDeviceToHost ) );
|
||||
CudaCheck( cudaMemcpy(y, cu_y, bcsr.m*sizeof(double), cudaMemcpyDeviceToHost ) );
|
||||
// Dealloc vectors
|
||||
// CHECK: CudaCheck(hipFree(cu_x));
|
||||
// CHECK: CudaCheck(hipFree(cu_y));
|
||||
CudaCheck(cudaFree(cu_x));
|
||||
CudaCheck(cudaFree(cu_y));
|
||||
return gemvComputeTume;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda.h>
|
||||
|
||||
__global__ void test_0() {
|
||||
int a = 10;
|
||||
}
|
||||
|
||||
namespace first {
|
||||
__global__ void test_1() {
|
||||
int b = 20;
|
||||
}
|
||||
namespace second {
|
||||
__global__ void test_2() {
|
||||
int c = 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// CHECK: hipLaunchKernelGGL(::test_0, dim3(1), dim3(1), 0, 0);
|
||||
::test_0<<<1, 1>>>();
|
||||
// CHECK: hipLaunchKernelGGL(first::test_1, dim3(1), dim3(1), 0, 0);
|
||||
first::test_1<<<1, 1>>>();
|
||||
// CHECK: hipLaunchKernelGGL(first::second::test_2, dim3(1), dim3(1), 0, 0);
|
||||
first::second::test_2<<<1, 1>>>();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args "--skip-excluded-preprocessor-conditional-blocks" %clang_args
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
|
||||
#include <cuda.h>
|
||||
|
||||
__global__ void axpy_kernel(float a, float* x, float* y) {
|
||||
y[threadIdx.x] = a * x[threadIdx.x];
|
||||
}
|
||||
|
||||
void axpy(float a, float* x, float* y) {
|
||||
|
||||
#ifdef SOME_MACRO
|
||||
// CHECK: axpy_kernel <<<1, 1>>> (a, y, x);
|
||||
axpy_kernel <<<1, 1>>> (a, y, x);
|
||||
#endif
|
||||
|
||||
#ifndef SOME_MACRO
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(2), 0, 0, a, y, x);
|
||||
axpy_kernel <<<1, 2>>> (a, y, x);
|
||||
#endif
|
||||
|
||||
#ifdef SOME_MACRO
|
||||
// CHECK: axpy_kernel <<<1, 3>>> (a, y, x);
|
||||
axpy_kernel <<<1, 3>>> (a, y, x);
|
||||
#else
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(4), 0, 0, a, x, y);
|
||||
axpy_kernel <<<1, 4>>> (a, x, y);
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args "--skip-excluded-preprocessor-conditional-blocks" %clang_args
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
|
||||
__global__ void axpy_kernel(float a, float* x, float* y) {
|
||||
y[threadIdx.x] = a * x[threadIdx.x];
|
||||
}
|
||||
|
||||
void axpy(float a, float* x, float* y) {
|
||||
float* y_new = nullptr;
|
||||
#ifdef SOME_MACRO
|
||||
y_new = x;
|
||||
// CHECK: axpy_kernel <<<1, 1>>> (a, y_new, x);
|
||||
axpy_kernel <<<1, 1>>> (a, y_new, x);
|
||||
#endif
|
||||
|
||||
#ifndef SOME_MACRO
|
||||
y_new = y;
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(2), 0, 0, a, y_new, x);
|
||||
axpy_kernel <<<1, 2>>> (a, y_new, x);
|
||||
#endif
|
||||
|
||||
#ifdef SOME_MACRO
|
||||
// CHECK: axpy_kernel <<<1, 3>>> (a, y, x);
|
||||
axpy_kernel <<<1, 3>>> (a, y, x);
|
||||
#else
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(4), 0, 0, a, x, y);
|
||||
axpy_kernel <<<1, 4>>> (a, x, y);
|
||||
#endif
|
||||
|
||||
#ifdef SOME_MACRO
|
||||
// CHECK: axpy_kernel <<<1, 5>>> (a, y, x);
|
||||
axpy_kernel <<<1, 5>>> (a, y, x);
|
||||
#elif defined SOME_MACRO_1
|
||||
// CHECK: axpy_kernel <<<1, 6>>> (a, x, y);
|
||||
axpy_kernel <<<1, 6>>> (a, x, y);
|
||||
#else
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(7), 0, 0, a, x, y);
|
||||
axpy_kernel <<<1, 7>>> (a, x, y);
|
||||
#endif
|
||||
|
||||
#ifndef SOME_MACRO
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(8), 0, 0, a, y, x);
|
||||
axpy_kernel <<<1, 8>>> (a, y, x);
|
||||
#elif !defined(SOME_MACRO_1)
|
||||
// CHECK: axpy_kernel <<<1, 9>>> (a, x, y);
|
||||
axpy_kernel <<<1, 9>>> (a, x, y);
|
||||
#else
|
||||
// CHECK: axpy_kernel <<<1, 10>>> (a, x, y);
|
||||
axpy_kernel <<<1, 10>>> (a, x, y);
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
|
||||
__global__ void axpy_kernel(float a, float* x, float* y) {
|
||||
y[threadIdx.x] = a * x[threadIdx.x];
|
||||
}
|
||||
|
||||
void axpy(float a, float* x, float* y) {
|
||||
float* y_new = nullptr;
|
||||
#ifdef SOME_MACRO
|
||||
y_new = x;
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(1), 0, 0, a, y_new, x);
|
||||
axpy_kernel <<<1, 1>>> (a, y_new, x);
|
||||
#endif
|
||||
|
||||
#ifndef SOME_MACRO
|
||||
y_new = y;
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(2), 0, 0, a, y_new, x);
|
||||
axpy_kernel <<<1, 2>>> (a, y_new, x);
|
||||
#endif
|
||||
|
||||
#ifdef SOME_MACRO
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(3), 0, 0, a, y, x);
|
||||
axpy_kernel <<<1, 3>>> (a, y, x);
|
||||
#else
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(4), 0, 0, a, x, y);
|
||||
axpy_kernel <<<1, 4>>> (a, x, y);
|
||||
#endif
|
||||
|
||||
#ifdef SOME_MACRO
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(5), 0, 0, a, y, x);
|
||||
axpy_kernel <<<1, 5>>> (a, y, x);
|
||||
#elif defined SOME_MACRO_1
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(6), 0, 0, a, x, y);
|
||||
axpy_kernel <<<1, 6>>> (a, x, y);
|
||||
#else
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(7), 0, 0, a, x, y);
|
||||
axpy_kernel <<<1, 7>>> (a, x, y);
|
||||
#endif
|
||||
|
||||
#ifndef SOME_MACRO
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(8), 0, 0, a, y, x);
|
||||
axpy_kernel <<<1, 8>>> (a, y, x);
|
||||
#elif !defined(SOME_MACRO_1)
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(9), 0, 0, a, x, y);
|
||||
axpy_kernel <<<1, 9>>> (a, x, y);
|
||||
#else
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(10), 0, 0, a, x, y);
|
||||
axpy_kernel <<<1, 10>>> (a, x, y);
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
|
||||
#include <cuda.h>
|
||||
|
||||
__global__ void axpy_kernel(float a, float* x, float* y) {
|
||||
y[threadIdx.x] = a * x[threadIdx.x];
|
||||
}
|
||||
|
||||
void axpy(float a, float* x, float* y) {
|
||||
|
||||
#ifdef SOME_MACRO
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(1), 0, 0, a, y, x);
|
||||
axpy_kernel <<<1, 1>>> (a, y, x);
|
||||
#endif
|
||||
|
||||
#ifndef SOME_MACRO
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(2), 0, 0, a, y, x);
|
||||
axpy_kernel <<<1, 2>>> (a, y, x);
|
||||
#endif
|
||||
|
||||
#ifdef SOME_MACRO
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(3), 0, 0, a, y, x);
|
||||
axpy_kernel <<<1, 3>>> (a, y, x);
|
||||
#else
|
||||
// CHECK: hipLaunchKernelGGL(axpy_kernel, dim3(1), dim3(4), 0, 0, a, x, y);
|
||||
axpy_kernel <<<1, 4>>> (a, x, y);
|
||||
#endif
|
||||
|
||||
}
|
||||
-130
@@ -1,130 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
/*
|
||||
Copyright (c) 2015-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.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda.h>
|
||||
|
||||
#define WIDTH 1024
|
||||
|
||||
#define NUM (WIDTH * WIDTH)
|
||||
|
||||
#define THREADS_PER_BLOCK_X 4
|
||||
#define THREADS_PER_BLOCK_Y 4
|
||||
#define THREADS_PER_BLOCK_Z 1
|
||||
|
||||
// Device (Kernel) function, it must be void
|
||||
__global__ void matrixTranspose(float* out, float* in, const int width) {
|
||||
int x = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
int y = blockDim.y * blockIdx.y + threadIdx.y;
|
||||
out[y * width + x] = in[x * width + y];
|
||||
}
|
||||
|
||||
// CPU implementation of matrix transpose
|
||||
void matrixTransposeCPUReference(float* output, float* input, const unsigned int width) {
|
||||
for (unsigned int j = 0; j < width; j++) {
|
||||
for (unsigned int i = 0; i < width; i++) {
|
||||
output[i * width + j] = input[j * width + i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
float* Matrix;
|
||||
float* TransposeMatrix;
|
||||
float* cpuTransposeMatrix;
|
||||
|
||||
float* gpuMatrix;
|
||||
float* gpuTransposeMatrix;
|
||||
|
||||
// CHECK: hipDeviceProp_t devProp;
|
||||
cudaDeviceProp devProp;
|
||||
// CHECK: hipGetDeviceProperties(&devProp, 0);
|
||||
cudaGetDeviceProperties(&devProp, 0);
|
||||
|
||||
std::cout << "Device name " << devProp.name << std::endl;
|
||||
|
||||
int i;
|
||||
int errors;
|
||||
|
||||
Matrix = (float*)malloc(NUM * sizeof(float));
|
||||
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
|
||||
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
|
||||
|
||||
// initialize the input data
|
||||
for (i = 0; i < NUM; i++) {
|
||||
Matrix[i] = (float)i * 10.0f;
|
||||
}
|
||||
|
||||
// allocate the memory on the device side
|
||||
// CHECK: hipMalloc((void**)&gpuMatrix, NUM * sizeof(float));
|
||||
cudaMalloc((void**)&gpuMatrix, NUM * sizeof(float));
|
||||
// CHECK: hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float));
|
||||
cudaMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float));
|
||||
|
||||
// Memory transfer from host to device
|
||||
// CHECK: hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice);
|
||||
cudaMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), cudaMemcpyHostToDevice);
|
||||
|
||||
// Lauching kernel from host
|
||||
|
||||
dim3 dimGrid(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y);
|
||||
dim3 dimBlock(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y);
|
||||
// CHECK: hipLaunchKernelGGL(matrixTranspose, dim3(dimGrid), dim3(dimBlock), 0, 0, gpuTransposeMatrix, gpuMatrix, WIDTH);
|
||||
matrixTranspose <<<dimGrid, dimBlock>>>(gpuTransposeMatrix, gpuMatrix, WIDTH);
|
||||
|
||||
// Memory transfer from device to host
|
||||
// CHECK: hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), cudaMemcpyDeviceToHost);
|
||||
|
||||
// CPU MatrixTranspose computation
|
||||
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
|
||||
|
||||
// verify the results
|
||||
errors = 0;
|
||||
double eps = 1.0E-6;
|
||||
for (i = 0; i < NUM; i++) {
|
||||
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
if (errors != 0) {
|
||||
printf("FAILED: %d errors\n", errors);
|
||||
} else {
|
||||
printf("PASSED!\n");
|
||||
}
|
||||
|
||||
// free the resources on device side
|
||||
// CHECK: hipFree(gpuMatrix);
|
||||
cudaFree(gpuMatrix);
|
||||
// CHECK: hipFree(gpuTransposeMatrix);
|
||||
cudaFree(gpuTransposeMatrix);
|
||||
|
||||
// free the resources on host side
|
||||
free(Matrix);
|
||||
free(TransposeMatrix);
|
||||
free(cpuTransposeMatrix);
|
||||
|
||||
return errors;
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
/*
|
||||
Copyright (c) 2015-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.
|
||||
*/
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda.h>
|
||||
// CHECK-NOT: #include <texture_fetch_functions.h>
|
||||
#include <texture_fetch_functions.h>
|
||||
|
||||
// CHECK: extern texture<float, 2, hipReadModeElementType> tex;
|
||||
extern texture<float, 2, cudaReadModeElementType> tex;
|
||||
|
||||
extern "C" __global__ void tex2dKernel(float* outputData, int width, int height) {
|
||||
int x = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
int y = blockDim.y * blockIdx.y + threadIdx.y;
|
||||
outputData[y * width + x] = tex2D(tex, x, y);
|
||||
}
|
||||
-169
@@ -1,169 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
/*
|
||||
Copyright (c) 2015-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.
|
||||
*/
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#define fileName "tex2dKernel.code"
|
||||
// CHECK: texture<float, 2, hipReadModeElementType> tex;
|
||||
texture<float, 2, cudaReadModeElementType> tex;
|
||||
bool testResult = false;
|
||||
|
||||
// CHECK: hipError_t status = cmd;
|
||||
// CHECK: if (status != hipSuccess) {
|
||||
// CHECK: std::cout << "error: #" << status << " (" << hipGetErrorString(status)
|
||||
#define CUDACHECK(cmd) \
|
||||
{ \
|
||||
cudaError_t status = cmd; \
|
||||
if (status != cudaSuccess) { \
|
||||
std::cout << "error: #" << status << " (" << cudaGetErrorString(status) \
|
||||
<< ") at line:" << __LINE__ << ": " << #cmd << std::endl; \
|
||||
abort(); \
|
||||
} \
|
||||
}
|
||||
|
||||
bool runTest(int argc, char** argv) {
|
||||
unsigned int width = 256;
|
||||
unsigned int height = 256;
|
||||
unsigned int size = width * height * sizeof(float);
|
||||
float* hData = (float*)malloc(size);
|
||||
memset(hData, 0, size);
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
hData[i * width + j] = i * width + j;
|
||||
}
|
||||
}
|
||||
// CHECK: hipModule_t Module;
|
||||
CUmodule Module;
|
||||
// CHECK: hipModuleLoad(&Module, fileName);
|
||||
cuModuleLoad(&Module, fileName);
|
||||
|
||||
// CHECK: hipArray * array;
|
||||
CUarray array;
|
||||
// CHECK: HIP_ARRAY_DESCRIPTOR desc;
|
||||
CUDA_ARRAY_DESCRIPTOR desc;
|
||||
// CHECK: desc.Format = HIP_AD_FORMAT_FLOAT;
|
||||
desc.Format = CU_AD_FORMAT_FLOAT;
|
||||
desc.NumChannels = 1;
|
||||
desc.Width = width;
|
||||
desc.Height = height;
|
||||
// CHECK: hipArrayCreate(&array, &desc);
|
||||
cuArrayCreate(&array, &desc);
|
||||
|
||||
// CHECK: hip_Memcpy2D copyParam;
|
||||
CUDA_MEMCPY2D copyParam;
|
||||
memset(©Param, 0, sizeof(copyParam));
|
||||
// CHECK: copyParam.dstMemoryType = hipMemoryTypeArray;
|
||||
copyParam.dstMemoryType = CU_MEMORYTYPE_ARRAY;
|
||||
copyParam.dstArray = array;
|
||||
// CHECK: copyParam.srcMemoryType = hipMemoryTypeHost;
|
||||
copyParam.srcMemoryType = CU_MEMORYTYPE_HOST;
|
||||
copyParam.srcHost = hData;
|
||||
copyParam.srcPitch = width * sizeof(float);
|
||||
copyParam.WidthInBytes = copyParam.srcPitch;
|
||||
copyParam.Height = height;
|
||||
// CHECK: hipMemcpyParam2D(©Param);
|
||||
cuMemcpy2D(©Param);
|
||||
|
||||
// CHECK: textureReference* texref;
|
||||
CUtexref_st* texref;
|
||||
// CHECK: hipModuleGetTexRef(&texref, Module, "tex");
|
||||
cuModuleGetTexRef(&texref, Module, "tex");
|
||||
// CHECK: hipTexRefSetAddressMode(texref, 0, hipAddressModeWrap);
|
||||
cuTexRefSetAddressMode(texref, 0, CU_TR_ADDRESS_MODE_WRAP);
|
||||
// CHECK: hipTexRefSetAddressMode(texref, 1, hipAddressModeWrap);
|
||||
cuTexRefSetAddressMode(texref, 1, CU_TR_ADDRESS_MODE_WRAP);
|
||||
// CHECK: hipTexRefSetFilterMode(texref, hipFilterModePoint);
|
||||
cuTexRefSetFilterMode(texref, CU_TR_FILTER_MODE_POINT);
|
||||
// CHECK: hipTexRefSetFlags(texref, 0);
|
||||
cuTexRefSetFlags(texref, 0);
|
||||
// CHECK: hipTexRefSetFormat(texref, HIP_AD_FORMAT_FLOAT, 1);
|
||||
cuTexRefSetFormat(texref, CU_AD_FORMAT_FLOAT, 1);
|
||||
// CHECK: hipTexRefSetArray(texref, array, HIP_TRSA_OVERRIDE_FORMAT);
|
||||
cuTexRefSetArray(texref, array, CU_TRSA_OVERRIDE_FORMAT);
|
||||
|
||||
float* dData = NULL;
|
||||
// CHECK: hipMalloc((void**)&dData, size);
|
||||
cudaMalloc((void**)&dData, size);
|
||||
|
||||
struct {
|
||||
void* _Ad;
|
||||
unsigned int _Bd;
|
||||
unsigned int _Cd;
|
||||
} args;
|
||||
args._Ad = (void*) dData;
|
||||
args._Bd = width;
|
||||
args._Cd = height;
|
||||
|
||||
size_t sizeTemp = sizeof(args);
|
||||
|
||||
// CHECK: void* config[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, &args, HIP_LAUNCH_PARAM_BUFFER_SIZE,
|
||||
// CHECK: &sizeTemp, HIP_LAUNCH_PARAM_END};
|
||||
void* config[] = {CU_LAUNCH_PARAM_BUFFER_POINTER, &args, CU_LAUNCH_PARAM_BUFFER_SIZE,
|
||||
&sizeTemp, CU_LAUNCH_PARAM_END};
|
||||
|
||||
// CHECK: hipFunction_t Function;
|
||||
CUfunction Function;
|
||||
// CHECK: hipModuleGetFunction(&Function, Module, "tex2dKernel");
|
||||
cuModuleGetFunction(&Function, Module, "tex2dKernel");
|
||||
|
||||
int temp1 = width / 16;
|
||||
int temp2 = height / 16;
|
||||
// CHECK: hipModuleLaunchKernel(Function, 16, 16, 1, temp1, temp2, 1, 0, 0, NULL, (void**)&config);
|
||||
cuLaunchKernel(Function, 16, 16, 1, temp1, temp2, 1, 0, 0, NULL, (void**)&config);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
float* hOutputData = (float*)malloc(size);
|
||||
memset(hOutputData, 0, size);
|
||||
// CHECK: hipMemcpy(hOutputData, dData, size, hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(hOutputData, dData, size, cudaMemcpyDeviceToHost);
|
||||
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
if (hData[i * width + j] != hOutputData[i * width + j]) {
|
||||
printf("Difference [ %d %d ]:%f ----%f\n", i, j, hData[i * width + j],
|
||||
hOutputData[i * width + j]);
|
||||
testResult = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// CHECK: hipFree(dData);
|
||||
cudaFree(dData);
|
||||
// CHECK: hipFreeArray(hipArray_t(array));
|
||||
cudaFreeArray(cudaArray_t(array));
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// CHECK: hipInit(0);
|
||||
cuInit(0);
|
||||
testResult = runTest(argc, argv);
|
||||
printf("%s ...\n", testResult ? "PASSED" : "FAILED");
|
||||
exit(testResult ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
-198
@@ -1,198 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
/*
|
||||
Copyright (c) 2015-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, 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.
|
||||
*/
|
||||
|
||||
// CHECK: #include "hip/hip_runtime.h"
|
||||
#include "cuda_runtime.h"
|
||||
#include <iostream>
|
||||
#define NUM 1000000
|
||||
|
||||
// CHECK: if (status != hipSuccess) {
|
||||
#define CUDA_CHECK(status) \
|
||||
if (status != cudaSuccess) { \
|
||||
std::cout << "Got Status: " << status << " at Line: " << __LINE__ << std::endl; \
|
||||
exit(0); \
|
||||
}
|
||||
|
||||
// Device (Kernel) function
|
||||
__global__ void multiply(float* C, float* A, float* B, int N) {
|
||||
int tx = blockDim.x*blockIdx.x+threadIdx.x;
|
||||
if (tx < N) {
|
||||
C[tx] = A[tx] * B[tx];
|
||||
}
|
||||
}
|
||||
|
||||
// CPU implementation
|
||||
void multiplyCPU(float* C, float* A, float* B, int N) {
|
||||
for(unsigned int i=0; i<N; i++) {
|
||||
C[i] = A[i] * B[i];
|
||||
}
|
||||
}
|
||||
|
||||
void launchKernel(float* C, float* A, float* B, bool manual) {
|
||||
// CHECK: hipDeviceProp_t devProp;
|
||||
cudaDeviceProp devProp;
|
||||
// CHECK: CUDA_CHECK(hipGetDeviceProperties(&devProp, 0));
|
||||
CUDA_CHECK(cudaGetDeviceProperties(&devProp, 0));
|
||||
|
||||
// CHECK: hipEvent_t start, stop;
|
||||
cudaEvent_t start, stop;
|
||||
// CHECK: CUDA_CHECK(hipEventCreate(&start));
|
||||
CUDA_CHECK(cudaEventCreate(&start));
|
||||
// CHECK: CUDA_CHECK(hipEventCreate(&stop));
|
||||
CUDA_CHECK(cudaEventCreate(&stop));
|
||||
float eventMs = 1.0f;
|
||||
const unsigned threadsperblock = 32;
|
||||
const unsigned blocks = (NUM/threadsperblock) + 1;
|
||||
|
||||
int mingridSize = 0;
|
||||
int gridSize = 0;
|
||||
int blockSize = 0;
|
||||
|
||||
if (manual) {
|
||||
blockSize = threadsperblock;
|
||||
gridSize = blocks;
|
||||
std::cout << std::endl << "Manual Configuration with block size " << blockSize << std::endl;
|
||||
} else {
|
||||
// CHECK: CUDA_CHECK(hipOccupancyMaxPotentialBlockSize(&mingridSize, &blockSize, multiply, 0, 0));
|
||||
CUDA_CHECK(cudaOccupancyMaxPotentialBlockSize(&mingridSize, &blockSize, multiply, 0, 0));
|
||||
std::cout << std::endl << "Automatic Configuation based on hipOccupancyMaxPotentialBlockSize " << std::endl;
|
||||
std::cout << "Suggested blocksize is " << blockSize << ", Minimum gridsize is " << mingridSize << std::endl;
|
||||
gridSize = (NUM/blockSize)+1;
|
||||
}
|
||||
|
||||
// Record the start event
|
||||
// CHECK: CUDA_CHECK(hipEventRecord(start, NULL));
|
||||
CUDA_CHECK(cudaEventRecord(start, NULL));
|
||||
|
||||
// Launching the Kernel from Host
|
||||
// CHECK: hipLaunchKernelGGL(multiply, dim3(gridSize), dim3(blockSize), 0, 0, C, A, B, NUM);
|
||||
multiply <<<gridSize , blockSize>>> (C, A, B, NUM);
|
||||
|
||||
// Record the stop event
|
||||
// CHECK: CUDA_CHECK(hipEventRecord(stop, NULL));
|
||||
CUDA_CHECK(cudaEventRecord(stop, NULL));
|
||||
// CHECK: CUDA_CHECK(hipEventSynchronize(stop));
|
||||
CUDA_CHECK(cudaEventSynchronize(stop));
|
||||
|
||||
// CHECK: CUDA_CHECK(hipEventElapsedTime(&eventMs, start, stop));
|
||||
CUDA_CHECK(cudaEventElapsedTime(&eventMs, start, stop));
|
||||
printf("kernel Execution time = %6.3fms\n", eventMs);
|
||||
|
||||
// Calculate Occupancy
|
||||
int numBlock = 0;
|
||||
// CHECK: CUDA_CHECK(hipOccupancyMaxActiveBlocksPerMultiprocessor(&numBlock, multiply, blockSize, 0));
|
||||
CUDA_CHECK(cudaOccupancyMaxActiveBlocksPerMultiprocessor(&numBlock, multiply, blockSize, 0));
|
||||
|
||||
if(devProp.maxThreadsPerMultiProcessor) {
|
||||
std::cout << "Theoretical Occupancy is " << (double)numBlock* blockSize/devProp.maxThreadsPerMultiProcessor * 100 << "%" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
float *A, *B, *C0, *C1, *cpuC;
|
||||
float *Ad, *Bd, *C0d, *C1d;
|
||||
int errors=0;
|
||||
|
||||
// Initialize the input data
|
||||
A = (float*)malloc(NUM * sizeof(float));
|
||||
B = (float*)malloc(NUM * sizeof(float));
|
||||
C0 = (float*)malloc(NUM * sizeof(float));
|
||||
C1 = (float*)malloc(NUM * sizeof(float));
|
||||
cpuC = (float*)malloc(NUM * sizeof(float));
|
||||
|
||||
for(int i=0; i< NUM; i++) {
|
||||
A[i] = i;
|
||||
B[i] = i;
|
||||
}
|
||||
|
||||
// Allocate the memory on the device side
|
||||
// CHECK: CUDA_CHECK(hipMalloc((void**)&Ad, NUM * sizeof(float)));
|
||||
CUDA_CHECK(cudaMalloc((void**)&Ad, NUM * sizeof(float)));
|
||||
// CHECK: CUDA_CHECK(hipMalloc((void**)&Bd, NUM * sizeof(float)));
|
||||
CUDA_CHECK(cudaMalloc((void**)&Bd, NUM * sizeof(float)));
|
||||
// CHECK: CUDA_CHECK(hipMalloc((void**)&C0d, NUM * sizeof(float)));
|
||||
CUDA_CHECK(cudaMalloc((void**)&C0d, NUM * sizeof(float)));
|
||||
// CHECK: CUDA_CHECK(hipMalloc((void**)&C1d, NUM * sizeof(float)));
|
||||
CUDA_CHECK(cudaMalloc((void**)&C1d, NUM * sizeof(float)));
|
||||
|
||||
// Memory transfer from host to device
|
||||
// CHECK: CUDA_CHECK(hipMemcpy(Ad,A,NUM * sizeof(float), hipMemcpyHostToDevice));
|
||||
CUDA_CHECK(cudaMemcpy(Ad,A,NUM * sizeof(float), cudaMemcpyHostToDevice));
|
||||
// CHECK: CUDA_CHECK(hipMemcpy(Bd,B,NUM * sizeof(float), hipMemcpyHostToDevice));
|
||||
CUDA_CHECK(cudaMemcpy(Bd,B,NUM * sizeof(float), cudaMemcpyHostToDevice));
|
||||
|
||||
// Kernel launch with manual/default block size
|
||||
launchKernel(C0d, Ad, Bd, 1);
|
||||
|
||||
// Kernel launch with the block size suggested by cudaOccupancyMaxPotentialBlockSize
|
||||
launchKernel(C1d, Ad, Bd, 0);
|
||||
|
||||
// Memory transfer from device to host
|
||||
// CHECK: CUDA_CHECK(hipMemcpy(C0,C0d, NUM * sizeof(float), hipMemcpyDeviceToHost));
|
||||
CUDA_CHECK(cudaMemcpy(C0,C0d, NUM * sizeof(float), cudaMemcpyDeviceToHost));
|
||||
// CHECK: CUDA_CHECK(hipMemcpy(C1,C1d, NUM * sizeof(float), hipMemcpyDeviceToHost));
|
||||
CUDA_CHECK(cudaMemcpy(C1,C1d, NUM * sizeof(float), cudaMemcpyDeviceToHost));
|
||||
|
||||
// CPU computation
|
||||
multiplyCPU(cpuC, A, B, NUM);
|
||||
|
||||
// Verify the results
|
||||
double eps = 1.0E-6;
|
||||
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
if (std::abs(C0[i] - cpuC[i]) > eps) {
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
if (errors != 0) {
|
||||
printf("\nManual Test FAILED: %d errors\n", errors);
|
||||
errors=0;
|
||||
} else {
|
||||
printf("\nManual Test PASSED!\n");
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
if (std::abs(C1[i] - cpuC[i]) > eps) {
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
if (errors != 0) {
|
||||
printf("\n Automatic Test FAILED: %d errors\n", errors);
|
||||
} else {
|
||||
printf("\nAutomatic Test PASSED!\n");
|
||||
}
|
||||
|
||||
// CHECK: CUDA_CHECK(hipFree(Ad));
|
||||
CUDA_CHECK(cudaFree(Ad));
|
||||
// CHECK: CUDA_CHECK(hipFree(Bd));
|
||||
CUDA_CHECK(cudaFree(Bd));
|
||||
// CHECK: CUDA_CHECK(hipFree(C0d));
|
||||
CUDA_CHECK(cudaFree(C0d));
|
||||
// CHECK: CUDA_CHECK(hipFree(C1d));
|
||||
CUDA_CHECK(cudaFree(C1d));
|
||||
|
||||
free(A);
|
||||
free(B);
|
||||
free(C0);
|
||||
free(C1);
|
||||
free(cpuC);
|
||||
}
|
||||
-181
@@ -1,181 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
/*
|
||||
Copyright (c) 2015-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.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda.h>
|
||||
|
||||
#define WIDTH 1024
|
||||
|
||||
#define NUM (WIDTH * WIDTH)
|
||||
|
||||
#define THREADS_PER_BLOCK_X 4
|
||||
#define THREADS_PER_BLOCK_Y 4
|
||||
#define THREADS_PER_BLOCK_Z 1
|
||||
|
||||
// Device (Kernel) function, it must be void
|
||||
__global__ void matrixTranspose(float* out, float* in, const int width) {
|
||||
int x = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
int y = blockDim.y * blockIdx.y + threadIdx.y;
|
||||
out[y * width + x] = in[x * width + y];
|
||||
}
|
||||
|
||||
// CPU implementation of matrix transpose
|
||||
void matrixTransposeCPUReference(float* output, float* input, const unsigned int width) {
|
||||
for (unsigned int j = 0; j < width; j++) {
|
||||
for (unsigned int i = 0; i < width; i++) {
|
||||
output[i * width + j] = input[j * width + i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
float* Matrix;
|
||||
float* TransposeMatrix;
|
||||
float* cpuTransposeMatrix;
|
||||
|
||||
float* gpuMatrix;
|
||||
float* gpuTransposeMatrix;
|
||||
|
||||
// CHECK: hipDeviceProp_t devProp;
|
||||
cudaDeviceProp devProp;
|
||||
// CHECK: hipGetDeviceProperties(&devProp, 0);
|
||||
cudaGetDeviceProperties(&devProp, 0);
|
||||
|
||||
std::cout << "Device name " << devProp.name << std::endl;
|
||||
|
||||
// CHECK: hipEvent_t start, stop;
|
||||
cudaEvent_t start, stop;
|
||||
// CHECK: hipEventCreate(&start);
|
||||
cudaEventCreate(&start);
|
||||
// CHECK: hipEventCreate(&stop);
|
||||
cudaEventCreate(&stop);
|
||||
float eventMs = 1.0f;
|
||||
|
||||
int i;
|
||||
int errors;
|
||||
|
||||
Matrix = (float*)malloc(NUM * sizeof(float));
|
||||
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
|
||||
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
|
||||
|
||||
// initialize the input data
|
||||
for (i = 0; i < NUM; i++) {
|
||||
Matrix[i] = (float)i * 10.0f;
|
||||
}
|
||||
|
||||
// allocate the memory on the device side
|
||||
// CHECK: hipMalloc((void**)&gpuMatrix, NUM * sizeof(float));
|
||||
cudaMalloc((void**)&gpuMatrix, NUM * sizeof(float));
|
||||
// CHECK: hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float));
|
||||
cudaMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float));
|
||||
|
||||
// Record the start event
|
||||
// CHECK: hipEventRecord(start, NULL);
|
||||
cudaEventRecord(start, NULL);
|
||||
|
||||
// Memory transfer from host to device
|
||||
// CHECK: hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice);
|
||||
cudaMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), cudaMemcpyHostToDevice);
|
||||
|
||||
// Record the stop event
|
||||
// CHECK: hipEventRecord(stop, NULL);
|
||||
cudaEventRecord(stop, NULL);
|
||||
// CHECK: hipEventSynchronize(stop);
|
||||
cudaEventSynchronize(stop);
|
||||
// CHECK: hipEventElapsedTime(&eventMs, start, stop);
|
||||
cudaEventElapsedTime(&eventMs, start, stop);
|
||||
|
||||
printf("hipMemcpyHostToDevice time taken = %6.3fms\n", eventMs);
|
||||
|
||||
// Record the start event
|
||||
// CHECK: hipEventRecord(start, NULL);
|
||||
cudaEventRecord(start, NULL);
|
||||
|
||||
// Lauching kernel from host
|
||||
|
||||
dim3 dimGrid(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y);
|
||||
dim3 dimBlock(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y);
|
||||
// CHECK: hipLaunchKernelGGL(matrixTranspose, dim3(dimGrid), dim3(dimBlock), 0, 0, gpuTransposeMatrix, gpuMatrix, WIDTH);
|
||||
matrixTranspose <<<dimGrid, dimBlock>>>(gpuTransposeMatrix, gpuMatrix, WIDTH);
|
||||
|
||||
// Record the stop event
|
||||
// CHECK: hipEventRecord(stop, NULL);
|
||||
cudaEventRecord(stop, NULL);
|
||||
// CHECK: hipEventSynchronize(stop);
|
||||
cudaEventSynchronize(stop);
|
||||
|
||||
// CHECK: hipEventElapsedTime(&eventMs, start, stop);
|
||||
cudaEventElapsedTime(&eventMs, start, stop);
|
||||
|
||||
printf("kernel Execution time = %6.3fms\n", eventMs);
|
||||
|
||||
// Record the start event
|
||||
// CHECK: hipEventRecord(start, NULL);
|
||||
cudaEventRecord(start, NULL);
|
||||
|
||||
// Memory transfer from device to host
|
||||
// CHECK: hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), cudaMemcpyDeviceToHost);
|
||||
|
||||
// Record the stop event
|
||||
// CHECK: hipEventRecord(stop, NULL);
|
||||
cudaEventRecord(stop, NULL);
|
||||
// CHECK: hipEventSynchronize(stop);
|
||||
cudaEventSynchronize(stop);
|
||||
// CHECK: hipEventElapsedTime(&eventMs, start, stop);
|
||||
cudaEventElapsedTime(&eventMs, start, stop);
|
||||
|
||||
printf("hipMemcpyDeviceToHost time taken = %6.3fms\n", eventMs);
|
||||
|
||||
// CPU MatrixTranspose computation
|
||||
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
|
||||
|
||||
// verify the results
|
||||
errors = 0;
|
||||
double eps = 1.0E-6;
|
||||
for (i = 0; i < NUM; i++) {
|
||||
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
if (errors != 0) {
|
||||
printf("FAILED: %d errors\n", errors);
|
||||
} else {
|
||||
printf("PASSED!\n");
|
||||
}
|
||||
|
||||
// free the resources on device side
|
||||
// CHECK: hipFree(gpuMatrix);
|
||||
cudaFree(gpuMatrix);
|
||||
// CHECK: hipFree(gpuTransposeMatrix);
|
||||
cudaFree(gpuTransposeMatrix);
|
||||
|
||||
// free the resources on host side
|
||||
free(Matrix);
|
||||
free(TransposeMatrix);
|
||||
free(cpuTransposeMatrix);
|
||||
|
||||
return errors;
|
||||
}
|
||||
-250
@@ -1,250 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
/*
|
||||
Copyright (c) 2015-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.
|
||||
*/
|
||||
|
||||
// NOTE: Profiler API is under development.
|
||||
// NOTE: This is NOT WORKING example.
|
||||
// TODO: Get rid of HIP_SCOPED_MARKER, HIP_BEGIN_MARKER, HIP_END_MARKER, declared in hip/hip_profile.h or
|
||||
// TODO: find out a way to hipify it in particular place (signatures are to obtain).
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda.h>
|
||||
// CHECK: #include <hip/hip_profile.h>
|
||||
#include <cuda_profiler_api.h>
|
||||
|
||||
#define WIDTH 1024
|
||||
|
||||
#define NUM (WIDTH * WIDTH)
|
||||
|
||||
#define THREADS_PER_BLOCK_X 4
|
||||
#define THREADS_PER_BLOCK_Y 4
|
||||
#define THREADS_PER_BLOCK_Z 1
|
||||
|
||||
#define ITERATIONS 10
|
||||
|
||||
// Cmdline parms to control start and stop triggers
|
||||
int startTriggerIteration = -1;
|
||||
int stopTriggerIteration = -1;
|
||||
|
||||
// Device (Kernel) function, it must be void
|
||||
__global__ void matrixTranspose(float* out, float* in, const int width) {
|
||||
int x = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
int y = blockDim.y * blockIdx.y + threadIdx.y;
|
||||
out[y * width + x] = in[x * width + y];
|
||||
}
|
||||
|
||||
// CPU implementation of matrix transpose
|
||||
void matrixTransposeCPUReference(float* output, float* input, const unsigned int width) {
|
||||
for (unsigned int j = 0; j < width; j++) {
|
||||
for (unsigned int i = 0; i < width; i++) {
|
||||
output[i * width + j] = input[j * width + i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use a separate function to demonstrate how to use function name as part of scoped marker:
|
||||
void runGPU(float* Matrix, float* TransposeMatrix, float* gpuMatrix, float* gpuTransposeMatrix) {
|
||||
// __func__ is a standard C++ macro which expands to the name of the function, in this case
|
||||
// "runGPU"
|
||||
// TODO: Find out signatures to generate the following:
|
||||
// HIP_SCOPED_MARKER(__func__, "MyGroup");
|
||||
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
if (i == startTriggerIteration) {
|
||||
// CHECK: hipProfilerStart();
|
||||
cudaProfilerStart();
|
||||
}
|
||||
if (i == stopTriggerIteration) {
|
||||
// CHECK: hipProfilerStop();
|
||||
cudaProfilerStop();
|
||||
}
|
||||
|
||||
float eventMs = 0.0f;
|
||||
|
||||
// CHECK: hipEvent_t start, stop;
|
||||
cudaEvent_t start, stop;
|
||||
// CHECK: hipEventCreate(&start);
|
||||
cudaEventCreate(&start);
|
||||
// CHECK: hipEventCreate(&stop);
|
||||
cudaEventCreate(&stop);
|
||||
|
||||
// Record the start event
|
||||
// CHECK: hipEventRecord(start, NULL);
|
||||
cudaEventRecord(start, NULL);
|
||||
|
||||
// Memory transfer from host to device
|
||||
// CHECK: hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice);
|
||||
cudaMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), cudaMemcpyHostToDevice);
|
||||
|
||||
// Record the stop event
|
||||
// CHECK: hipEventRecord(stop, NULL);
|
||||
cudaEventRecord(stop, NULL);
|
||||
// CHECK: hipEventSynchronize(stop);
|
||||
cudaEventSynchronize(stop);
|
||||
|
||||
// CHECK: hipEventElapsedTime(&eventMs, start, stop);
|
||||
cudaEventElapsedTime(&eventMs, start, stop);
|
||||
|
||||
// CHECK: printf("hipMemcpyHostToDevice time taken = %6.3fms\n", eventMs);
|
||||
printf("cudaMemcpyHostToDevice time taken = %6.3fms\n", eventMs);
|
||||
|
||||
// Record the start event
|
||||
// CHECK: hipEventRecord(start, NULL);
|
||||
cudaEventRecord(start, NULL);
|
||||
|
||||
// Lauching kernel from host
|
||||
dim3 dimGrid(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y);
|
||||
dim3 dimBlock(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y);
|
||||
// CHECK: hipLaunchKernelGGL(matrixTranspose, dim3(dimGrid), dim3(dimBlock), 0, 0, gpuTransposeMatrix, gpuMatrix, WIDTH);
|
||||
matrixTranspose <<<dimGrid, dimBlock >>> (gpuTransposeMatrix, gpuMatrix, WIDTH);
|
||||
|
||||
// Record the stop event
|
||||
// CHECK: hipEventRecord(stop, NULL);
|
||||
cudaEventRecord(stop, NULL);
|
||||
// CHECK: hipEventSynchronize(stop);
|
||||
cudaEventSynchronize(stop);
|
||||
// CHECK: hipEventElapsedTime(&eventMs, start, stop);
|
||||
cudaEventElapsedTime(&eventMs, start, stop);
|
||||
|
||||
printf("kernel Execution time = %6.3fms\n", eventMs);
|
||||
|
||||
// Record the start event
|
||||
// CHECK: hipEventRecord(start, NULL);
|
||||
cudaEventRecord(start, NULL);
|
||||
|
||||
// Memory transfer from device to host
|
||||
// CHECK: hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), cudaMemcpyDeviceToHost);
|
||||
|
||||
// Record the stop event
|
||||
// CHECK: hipEventRecord(stop, NULL);
|
||||
cudaEventRecord(stop, NULL);
|
||||
// CHECK: hipEventSynchronize(stop);
|
||||
cudaEventSynchronize(stop);
|
||||
|
||||
// CHECK: hipEventElapsedTime(&eventMs, start, stop);
|
||||
cudaEventElapsedTime(&eventMs, start, stop);
|
||||
|
||||
// CHECK: printf("hipMemcpyDeviceToHost time taken = %6.3fms\n", eventMs);
|
||||
printf("cudaMemcpyDeviceToHost time taken = %6.3fms\n", eventMs);
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc >= 2) {
|
||||
startTriggerIteration = atoi(argv[1]);
|
||||
printf("info : will start tracing at iteration:%d\n", startTriggerIteration);
|
||||
}
|
||||
if (argc >= 3) {
|
||||
stopTriggerIteration = atoi(argv[2]);
|
||||
printf("info : will stop tracing at iteration:%d\n", stopTriggerIteration);
|
||||
}
|
||||
|
||||
float* Matrix;
|
||||
float* TransposeMatrix;
|
||||
float* cpuTransposeMatrix;
|
||||
|
||||
float* gpuMatrix;
|
||||
float* gpuTransposeMatrix;
|
||||
|
||||
// CHECK: hipDeviceProp_t devProp;
|
||||
cudaDeviceProp devProp;
|
||||
// CHECK: hipGetDeviceProperties(&devProp, 0);
|
||||
cudaGetDeviceProperties(&devProp, 0);
|
||||
|
||||
std::cout << "Device name " << devProp.name << std::endl;
|
||||
|
||||
{
|
||||
// Show example of how to create a "scoped marker".
|
||||
// The scoped marker records the time spent inside the { scope } of the marker - the begin
|
||||
// timestamp is at the beginning of the code scope, and the end is recorded when the SCOPE
|
||||
// exits. This can be viewed in CodeXL timeline relative to other GPU and CPU events. This
|
||||
// marker captures the time spent in setup including host allocation, initialization, and
|
||||
// device memory allocation.
|
||||
// TODO: Find out signatures to generate the following:
|
||||
// HIP_SCOPED_MARKER("Setup", "MyGroup");
|
||||
|
||||
Matrix = (float*)malloc(NUM * sizeof(float));
|
||||
TransposeMatrix = (float*)malloc(NUM * sizeof(float));
|
||||
cpuTransposeMatrix = (float*)malloc(NUM * sizeof(float));
|
||||
|
||||
// initialize the input data
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
Matrix[i] = (float)i * 10.0f;
|
||||
}
|
||||
|
||||
// allocate the memory on the device side
|
||||
// CHECK: hipMalloc((void**)&gpuMatrix, NUM * sizeof(float));
|
||||
cudaMalloc((void**)&gpuMatrix, NUM * sizeof(float));
|
||||
// CHECK: hipMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float));
|
||||
cudaMalloc((void**)&gpuTransposeMatrix, NUM * sizeof(float));
|
||||
|
||||
// FYI, the scoped-marker will be destroyed here when the scope exits, and will record its
|
||||
// "end" timestamp.
|
||||
}
|
||||
|
||||
runGPU(Matrix, TransposeMatrix, gpuMatrix, gpuTransposeMatrix);
|
||||
|
||||
// show how to use explicit begin/end markers:
|
||||
// We begin the timed region with HIP_BEGIN_MARKER, passing in the markerName and group:
|
||||
// The region will stop when HIP_END_MARKER is called
|
||||
// This is another way to mark begin/end - as an alternative to scoped markers.
|
||||
// TODO: Find out signatures to generate the following:
|
||||
// HIP_BEGIN_MARKER("Check&TearDown", "MyGroup");
|
||||
|
||||
int errors = 0;
|
||||
|
||||
// CPU MatrixTranspose computation
|
||||
matrixTransposeCPUReference(cpuTransposeMatrix, Matrix, WIDTH);
|
||||
|
||||
// verify the results
|
||||
double eps = 1.0E-6;
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
if (std::abs(TransposeMatrix[i] - cpuTransposeMatrix[i]) > eps) {
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
if (errors != 0) {
|
||||
printf("FAILED: %d errors\n", errors);
|
||||
} else {
|
||||
printf("PASSED!\n");
|
||||
}
|
||||
|
||||
// free the resources on device side
|
||||
// CHECK: hipFree(gpuMatrix);
|
||||
cudaFree(gpuMatrix);
|
||||
// CHECK: hipFree(gpuTransposeMatrix);
|
||||
cudaFree(gpuTransposeMatrix);
|
||||
|
||||
// free the resources on host side
|
||||
free(Matrix);
|
||||
free(TransposeMatrix);
|
||||
free(cpuTransposeMatrix);
|
||||
|
||||
// This ends the last marker started in this thread, in this case "Check&TearDown"
|
||||
// TODO: Find out signatures to generate the following:
|
||||
// HIP_END_MARKER();
|
||||
|
||||
return errors;
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
/*
|
||||
Copyright (c) 2015-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.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda.h>
|
||||
|
||||
#define WIDTH 32
|
||||
|
||||
#define NUM (WIDTH * WIDTH)
|
||||
|
||||
#define THREADS_PER_BLOCK_X 4
|
||||
#define THREADS_PER_BLOCK_Y 4
|
||||
#define THREADS_PER_BLOCK_Z 1
|
||||
|
||||
using namespace std;
|
||||
|
||||
__global__ void matrixTranspose_static_shared(float* out, float* in,
|
||||
const int width) {
|
||||
// CHECK-NOT: HIP_DYNAMIC_SHARED(float, sharedMem);
|
||||
// CHECK: __shared__ float sharedMem[WIDTH * WIDTH];
|
||||
__shared__ float sharedMem[WIDTH * WIDTH];
|
||||
|
||||
int x = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
int y = blockDim.y * blockIdx.y + threadIdx.y;
|
||||
|
||||
sharedMem[y * width + x] = in[x * width + y];
|
||||
|
||||
__syncthreads();
|
||||
|
||||
out[y * width + x] = sharedMem[y * width + x];
|
||||
}
|
||||
|
||||
__global__ void matrixTranspose_dynamic_shared(float* out, float* in,
|
||||
const int width) {
|
||||
// declare dynamic shared memory
|
||||
// CHECK-NOT: extern __shared__
|
||||
// CHECK: HIP_DYNAMIC_SHARED(int, sharedMem)
|
||||
extern __shared__ int sharedMem[];
|
||||
|
||||
int x = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
int y = blockDim.y * blockIdx.y + threadIdx.y;
|
||||
|
||||
sharedMem[y * width + x] = in[x * width + y];
|
||||
|
||||
__syncthreads();
|
||||
|
||||
out[y * width + x] = sharedMem[y * width + x];
|
||||
}
|
||||
|
||||
void MultipleStream(float** data, float* randArray, float** gpuTransposeMatrix,
|
||||
float** TransposeMatrix, int width) {
|
||||
const int num_streams = 2;
|
||||
// CHECK: hipStream_t streams[num_streams];
|
||||
cudaStream_t streams[num_streams];
|
||||
|
||||
// CHECK: for (int i = 0; i < num_streams; i++) hipStreamCreate(&streams[i]);
|
||||
for (int i = 0; i < num_streams; i++) cudaStreamCreate(&streams[i]);
|
||||
|
||||
for (int i = 0; i < num_streams; i++) {
|
||||
// CHECK: hipMalloc((void**)&data[i], NUM * sizeof(float));
|
||||
cudaMalloc((void**)&data[i], NUM * sizeof(float));
|
||||
// CHECK: hipMemcpyAsync(data[i], randArray, NUM * sizeof(float), hipMemcpyHostToDevice, streams[i]);
|
||||
cudaMemcpyAsync(data[i], randArray, NUM * sizeof(float), cudaMemcpyHostToDevice, streams[i]);
|
||||
}
|
||||
|
||||
dim3 dimGrid(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y);
|
||||
dim3 dimBlock(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y);
|
||||
// CHECK: hipLaunchKernelGGL(matrixTranspose_static_shared, dim3(dimGrid), dim3(dimBlock), 0, streams[0], gpuTransposeMatrix[0], data[0], width);
|
||||
matrixTranspose_static_shared <<<dimGrid, dimBlock, 0, streams[0]>>>(gpuTransposeMatrix[0], data[0], width);
|
||||
// CHECK: hipLaunchKernelGGL(matrixTranspose_dynamic_shared, dim3(dimGrid), dim3(dimBlock), 0, streams[1], gpuTransposeMatrix[1], data[1], width);
|
||||
matrixTranspose_dynamic_shared <<<dimGrid, dimBlock, 0, streams[1]>>>(gpuTransposeMatrix[1], data[1], width);
|
||||
|
||||
for (int i = 0; i < num_streams; i++)
|
||||
// CHECK: hipMemcpyAsync(TransposeMatrix[i], gpuTransposeMatrix[i], NUM * sizeof(float), hipMemcpyDeviceToHost, streams[i]);
|
||||
cudaMemcpyAsync(TransposeMatrix[i], gpuTransposeMatrix[i], NUM * sizeof(float), cudaMemcpyDeviceToHost, streams[i]);
|
||||
}
|
||||
|
||||
int main() {
|
||||
// CHECK: hipSetDevice(0);
|
||||
cudaSetDevice(0);
|
||||
|
||||
float *data[2], *TransposeMatrix[2], *gpuTransposeMatrix[2], *randArray;
|
||||
|
||||
int width = WIDTH;
|
||||
|
||||
randArray = (float*)malloc(NUM * sizeof(float));
|
||||
|
||||
TransposeMatrix[0] = (float*)malloc(NUM * sizeof(float));
|
||||
TransposeMatrix[1] = (float*)malloc(NUM * sizeof(float));
|
||||
|
||||
// CHECK: hipMalloc((void**)&gpuTransposeMatrix[0], NUM * sizeof(float));
|
||||
cudaMalloc((void**)&gpuTransposeMatrix[0], NUM * sizeof(float));
|
||||
// CHECK: hipMalloc((void**)&gpuTransposeMatrix[1], NUM * sizeof(float));
|
||||
cudaMalloc((void**)&gpuTransposeMatrix[1], NUM * sizeof(float));
|
||||
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
randArray[i] = (float)i * 1.0f;
|
||||
}
|
||||
|
||||
MultipleStream(data, randArray, gpuTransposeMatrix, TransposeMatrix, width);
|
||||
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
// verify the results
|
||||
int errors = 0;
|
||||
double eps = 1.0E-6;
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
if (std::abs(TransposeMatrix[0][i] - TransposeMatrix[1][i]) > eps) {
|
||||
printf("%d stream0: %f stream1 %f\n", i, TransposeMatrix[0][i], TransposeMatrix[1][i]);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
if (errors != 0) {
|
||||
printf("FAILED: %d errors\n", errors);
|
||||
} else {
|
||||
printf("stream PASSED!\n");
|
||||
}
|
||||
|
||||
free(randArray);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
// CHECK: hipFree(data[i]);
|
||||
cudaFree(data[i]);
|
||||
// CHECK: hipFree(gpuTransposeMatrix[i]);
|
||||
cudaFree(gpuTransposeMatrix[i]);
|
||||
free(TransposeMatrix[i]);
|
||||
}
|
||||
|
||||
// CHECK: hipDeviceReset();
|
||||
cudaDeviceReset();
|
||||
return 0;
|
||||
}
|
||||
-225
@@ -1,225 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
/*
|
||||
Copyright (c) 2015-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.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda.h>
|
||||
#include <assert.h>
|
||||
#define WIDTH 32
|
||||
|
||||
#define NUM (WIDTH * WIDTH)
|
||||
|
||||
#define THREADS_PER_BLOCK_X 4
|
||||
#define THREADS_PER_BLOCK_Y 4
|
||||
#define THREADS_PER_BLOCK_Z 1
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define KNRM "\x1B[0m"
|
||||
#define KRED "\x1B[31m"
|
||||
|
||||
#define failed(...) \
|
||||
printf("%serror: ", KRED); \
|
||||
printf(__VA_ARGS__); \
|
||||
printf("\n"); \
|
||||
printf("error: TEST FAILED\n%s", KNRM); \
|
||||
abort();
|
||||
|
||||
// CHECK: hipError_t localError = error;
|
||||
// CHECK: if ((localError != hipSuccess) && (localError != hipErrorPeerAccessAlreadyEnabled) &&
|
||||
// CHECK: (localError != hipErrorPeerAccessNotEnabled )) {
|
||||
// CHECK: printf("%serror: '%s'(%d) from %s at %s:%d%s\n", KRED, hipGetErrorString(localError),
|
||||
#define CUDACHECK(error) \
|
||||
{ \
|
||||
cudaError_t localError = error; \
|
||||
if ((localError != cudaSuccess) && (localError != cudaErrorPeerAccessAlreadyEnabled) && \
|
||||
(localError != cudaErrorPeerAccessNotEnabled )) { \
|
||||
printf("%serror: '%s'(%d) from %s at %s:%d%s\n", KRED, cudaGetErrorString(localError), \
|
||||
localError, #error, __FILE__, __LINE__, KNRM); \
|
||||
failed("API returned error code."); \
|
||||
} \
|
||||
}
|
||||
|
||||
void checkPeer2PeerSupport() {
|
||||
int gpuCount;
|
||||
int canAccessPeer;
|
||||
// CHECK: CUDACHECK(hipGetDeviceCount(&gpuCount));
|
||||
CUDACHECK(cudaGetDeviceCount(&gpuCount));
|
||||
for (int currentGpu = 0; currentGpu < gpuCount; currentGpu++) {
|
||||
// CHECK: CUDACHECK(hipSetDevice(currentGpu));
|
||||
CUDACHECK(cudaSetDevice(currentGpu));
|
||||
for (int peerGpu = 0; peerGpu < currentGpu; peerGpu++) {
|
||||
if (currentGpu != peerGpu) {
|
||||
// CHECK: CUDACHECK(hipDeviceCanAccessPeer(&canAccessPeer, currentGpu, peerGpu));
|
||||
CUDACHECK(cudaDeviceCanAccessPeer(&canAccessPeer, currentGpu, peerGpu));
|
||||
printf("currentGpu#%d canAccessPeer: peerGpu#%d=%d\n", currentGpu, peerGpu,
|
||||
canAccessPeer);
|
||||
}
|
||||
// CHECK: CUDACHECK(hipSetDevice(peerGpu));
|
||||
CUDACHECK(cudaSetDevice(peerGpu));
|
||||
// CHECK: CUDACHECK(hipDeviceReset());
|
||||
CUDACHECK(cudaDeviceReset());
|
||||
}
|
||||
// CHECK: CUDACHECK(hipSetDevice(currentGpu));
|
||||
CUDACHECK(cudaSetDevice(currentGpu));
|
||||
// CHECK: CUDACHECK(hipDeviceReset());
|
||||
CUDACHECK(cudaDeviceReset());
|
||||
}
|
||||
}
|
||||
|
||||
void enablePeer2Peer(int currentGpu, int peerGpu) {
|
||||
int canAccessPeer;
|
||||
// Must be on a multi-gpu system:
|
||||
assert(currentGpu != peerGpu);
|
||||
// CHECK: CUDACHECK(hipSetDevice(currentGpu));
|
||||
CUDACHECK(cudaSetDevice(currentGpu));
|
||||
// CHECK: hipDeviceCanAccessPeer(&canAccessPeer, currentGpu, peerGpu);
|
||||
cudaDeviceCanAccessPeer(&canAccessPeer, currentGpu, peerGpu);
|
||||
if (canAccessPeer == 1) {
|
||||
// CHECK: CUDACHECK(hipDeviceEnablePeerAccess(peerGpu, 0));
|
||||
CUDACHECK(cudaDeviceEnablePeerAccess(peerGpu, 0));
|
||||
} else
|
||||
printf("peer2peer transfer not possible between the selected gpu devices");
|
||||
}
|
||||
|
||||
void disablePeer2Peer(int currentGpu, int peerGpu) {
|
||||
int canAccessPeer;
|
||||
// Must be on a multi-gpu system:
|
||||
assert(currentGpu != peerGpu);
|
||||
// CHECK: CUDACHECK(hipSetDevice(currentGpu));
|
||||
CUDACHECK(cudaSetDevice(currentGpu));
|
||||
// CHECK: hipDeviceCanAccessPeer(&canAccessPeer, currentGpu, peerGpu);
|
||||
cudaDeviceCanAccessPeer(&canAccessPeer, currentGpu, peerGpu);
|
||||
if (canAccessPeer == 1) {
|
||||
// CHECK: CUDACHECK(hipDeviceDisablePeerAccess(peerGpu));
|
||||
CUDACHECK(cudaDeviceDisablePeerAccess(peerGpu));
|
||||
} else
|
||||
printf("peer2peer disable not required");
|
||||
}
|
||||
|
||||
__global__ void matrixTranspose_static_shared(float* out, float* in,
|
||||
const int width) {
|
||||
// CHECK-NOT: HIP_DYNAMIC_SHARED(float, sharedMem);
|
||||
// CHECK: __shared__ float sharedMem[WIDTH * WIDTH];
|
||||
__shared__ float sharedMem[WIDTH * WIDTH];
|
||||
int x = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
int y = blockDim.y * blockIdx.y + threadIdx.y;
|
||||
sharedMem[y * width + x] = in[x * width + y];
|
||||
__syncthreads();
|
||||
out[y * width + x] = sharedMem[y * width + x];
|
||||
}
|
||||
|
||||
__global__ void matrixTranspose_dynamic_shared(float* out, float* in,
|
||||
const int width) {
|
||||
// declare dynamic shared memory
|
||||
// CHECK-NOT: extern __shared__
|
||||
// CHECK: HIP_DYNAMIC_SHARED(float, sharedMem)
|
||||
extern __shared__ float sharedMem[];
|
||||
int x = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
int y = blockDim.y * blockIdx.y + threadIdx.y;
|
||||
sharedMem[y * width + x] = in[x * width + y];
|
||||
__syncthreads();
|
||||
out[y * width + x] = sharedMem[y * width + x];
|
||||
}
|
||||
|
||||
int main() {
|
||||
checkPeer2PeerSupport();
|
||||
int gpuCount;
|
||||
int currentGpu, peerGpu;
|
||||
// CHECK: CUDACHECK(hipGetDeviceCount(&gpuCount));
|
||||
CUDACHECK(cudaGetDeviceCount(&gpuCount));
|
||||
if (gpuCount < 2) {
|
||||
printf("Peer2Peer application requires atleast 2 gpu devices");
|
||||
return 0;
|
||||
}
|
||||
currentGpu = 0;
|
||||
peerGpu = (currentGpu + 1);
|
||||
printf("currentGpu=%d peerGpu=%d (Total no. of gpu = %d)\n", currentGpu, peerGpu, gpuCount);
|
||||
float *data[2], *TransposeMatrix[2], *gpuTransposeMatrix[2], *randArray;
|
||||
int width = WIDTH;
|
||||
randArray = (float*)malloc(NUM * sizeof(float));
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
randArray[i] = (float)i * 1.0f;
|
||||
}
|
||||
enablePeer2Peer(currentGpu, peerGpu);
|
||||
// CHECK: CUDACHECK(hipSetDevice(currentGpu));
|
||||
CUDACHECK(cudaSetDevice(currentGpu));
|
||||
TransposeMatrix[0] = (float*)malloc(NUM * sizeof(float));
|
||||
// CHECK: hipMalloc((void**)&gpuTransposeMatrix[0], NUM * sizeof(float));
|
||||
cudaMalloc((void**)&gpuTransposeMatrix[0], NUM * sizeof(float));
|
||||
// CHECK: hipMalloc((void**)&data[0], NUM * sizeof(float));
|
||||
cudaMalloc((void**)&data[0], NUM * sizeof(float));
|
||||
// CHECK: hipMemcpy(data[0], randArray, NUM * sizeof(float), hipMemcpyHostToDevice);
|
||||
cudaMemcpy(data[0], randArray, NUM * sizeof(float), cudaMemcpyHostToDevice);
|
||||
dim3 dimGrid(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y);
|
||||
dim3 dimBlock(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y);
|
||||
// CHECK: hipLaunchKernelGGL(matrixTranspose_static_shared, dim3(dimGrid), dim3(dimBlock), 0, 0, gpuTransposeMatrix[0], data[0], width);
|
||||
matrixTranspose_static_shared <<<dimGrid, dimBlock>>>(gpuTransposeMatrix[0], data[0], width);
|
||||
// CHECK: CUDACHECK(hipSetDevice(peerGpu));
|
||||
CUDACHECK(cudaSetDevice(peerGpu));
|
||||
TransposeMatrix[1] = (float*)malloc(NUM * sizeof(float));
|
||||
// CHECK: hipMalloc((void**)&gpuTransposeMatrix[1], NUM * sizeof(float));
|
||||
cudaMalloc((void**)&gpuTransposeMatrix[1], NUM * sizeof(float));
|
||||
// CHECK: hipMalloc((void**)&data[1], NUM * sizeof(float));
|
||||
cudaMalloc((void**)&data[1], NUM * sizeof(float));
|
||||
// CHECK: hipMemcpy(data[1], gpuTransposeMatrix[0], NUM * sizeof(float), hipMemcpyDeviceToDevice);
|
||||
cudaMemcpy(data[1], gpuTransposeMatrix[0], NUM * sizeof(float), cudaMemcpyDeviceToDevice);
|
||||
// CHECK: hipLaunchKernelGGL(matrixTranspose_dynamic_shared, dim3(dimGrid), dim3(dimBlock), sizeof(float) * WIDTH * WIDTH, 0, gpuTransposeMatrix[1], data[1], width);
|
||||
matrixTranspose_dynamic_shared <<<dimGrid, dimBlock, sizeof(float) * WIDTH * WIDTH>>>(gpuTransposeMatrix[1], data[1], width);
|
||||
// CHECK: hipMemcpy(TransposeMatrix[1], gpuTransposeMatrix[1], NUM * sizeof(float), hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(TransposeMatrix[1], gpuTransposeMatrix[1], NUM * sizeof(float), cudaMemcpyDeviceToHost);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
disablePeer2Peer(currentGpu, peerGpu);
|
||||
// verify the results
|
||||
int errors = 0;
|
||||
double eps = 1.0E-6;
|
||||
for (int i = 0; i < NUM; i++) {
|
||||
if (std::abs(randArray[i] - TransposeMatrix[1][i]) > eps) {
|
||||
printf("%d cpu: %f gpu peered data %f\n", i, randArray[i], TransposeMatrix[1][i]);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
if (errors != 0) {
|
||||
printf("FAILED: %d errors\n", errors);
|
||||
} else {
|
||||
printf("Peer2Peer PASSED!\n");
|
||||
}
|
||||
free(randArray);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
// CHECK: hipFree(data[i]);
|
||||
cudaFree(data[i]);
|
||||
// CHECK: hipFree(gpuTransposeMatrix[i]);
|
||||
cudaFree(gpuTransposeMatrix[i]);
|
||||
free(TransposeMatrix[i]);
|
||||
}
|
||||
// CHECK: CUDACHECK(hipSetDevice(peerGpu));
|
||||
CUDACHECK(cudaSetDevice(peerGpu));
|
||||
// CHECK: CUDACHECK(hipDeviceReset());
|
||||
CUDACHECK(cudaDeviceReset());
|
||||
// CHECK: CUDACHECK(hipSetDevice(currentGpu));
|
||||
CUDACHECK(cudaSetDevice(currentGpu));
|
||||
// CHECK: CUDACHECK(hipDeviceReset());
|
||||
CUDACHECK(cudaDeviceReset());
|
||||
return 0;
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <math.h>
|
||||
|
||||
__global__
|
||||
void add(int n, float *x, float *y)
|
||||
{
|
||||
int index = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int stride = blockDim.x * gridDim.x;
|
||||
for (int i = index; i < n; i += stride)
|
||||
y[i] = x[i] + y[i];
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int numElements = 10;
|
||||
bool testResult = true;
|
||||
float *A, *B;
|
||||
// CHECK: hipMallocManaged(&A, numElements * sizeof(float));
|
||||
cudaMallocManaged(&A, numElements * sizeof(float));
|
||||
// CHECK: hipMallocManaged(&B, numElements * sizeof(float));
|
||||
cudaMallocManaged(&B, numElements * sizeof(float));
|
||||
for (int i = 0; i < numElements; i++) {
|
||||
A[i] = 1.0f;
|
||||
B[i] = 2.0f;
|
||||
}
|
||||
int blockSize = 256;
|
||||
int numBlocks = (numElements + blockSize - 1) / blockSize;
|
||||
dim3 dimGrid(numBlocks, 1, 1);
|
||||
dim3 dimBlock(blockSize, 1, 1);
|
||||
// CHECK: hipLaunchKernelGGL(add, dim3(dimGrid), dim3(dimBlock), 0, 0, numElements, A, B);
|
||||
add<<<dimGrid, dimBlock>>>(numElements, A, B);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
float maxError = 0.0f;
|
||||
for (int i = 0; i < numElements; i++)
|
||||
maxError = fmax(maxError, fabs(B[i]-3.0f));
|
||||
// CHECK: hipFree(A);
|
||||
cudaFree(A);
|
||||
// CHECK: hipFree(B);
|
||||
cudaFree(B);
|
||||
if(maxError == 0.0f)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
#pragma once
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda_runtime.h>
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* Allocate GPU memory for `count` elements of type `T`.
|
||||
*/
|
||||
template<typename T>
|
||||
static T* gpuMalloc(size_t count) {
|
||||
T* ret = nullptr;
|
||||
// CHECK: hipMalloc(&ret, count * sizeof(T));
|
||||
cudaMalloc(&ret, count * sizeof(T));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
__global__ void add(int n, T* x, T* y) {
|
||||
int index = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
int stride = blockDim.x * gridDim.x;
|
||||
for (int i = index; i < n; i += stride)
|
||||
y[i] = x[i] + y[i];
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
size_t numElements = 50;
|
||||
float *A = gpuMalloc<float>(numElements);
|
||||
float* B = gpuMalloc<float>(numElements);
|
||||
for (int i = 0; i < numElements; ++i) {
|
||||
A[i] = 1.0f;
|
||||
B[i] = 2.0f;
|
||||
}
|
||||
int blockSize = 512;
|
||||
int numBlocks = (numElements + blockSize - 1) / blockSize;
|
||||
dim3 dimGrid(numBlocks, 1, 1);
|
||||
dim3 dimBlock(blockSize, 1, 1);
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(add<float>), dim3(dimGrid), dim3(dimBlock), 0, 0, numElements, A, B);
|
||||
add<float><<<dimGrid, dimBlock>>>(numElements, A, B);
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
float maxError = 0.0f;
|
||||
for (int i = 0; i < numElements; ++i)
|
||||
maxError = fmax(maxError, fabs(B[i] - 3.0f));
|
||||
// CHECK: hipFree(A);
|
||||
cudaFree(A);
|
||||
// CHECK: hipFree(B);
|
||||
cudaFree(B);
|
||||
if (maxError == 0.0f)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda.h>
|
||||
|
||||
#define TOKEN_PASTE(X, Y) X ## Y
|
||||
#define ARG_LIST_AS_MACRO a, device_x, device_y
|
||||
#define KERNEL_CALL_AS_MACRO axpy<float><<<1, kDataLen>>>
|
||||
#define KERNEL_NAME_MACRO axpy<float>
|
||||
|
||||
// CHECK: #define COMPLETE_LAUNCH hipLaunchKernelGGL(HIP_KERNEL_NAME(axpy), dim3(1), dim3(kDataLen), 0, 0, a, device_x, device_y)
|
||||
#define COMPLETE_LAUNCH axpy<<<1, kDataLen>>>(a, device_x, device_y)
|
||||
|
||||
|
||||
template<typename T>
|
||||
__global__ void axpy(T a, T *x, T *y) {
|
||||
y[threadIdx.x] = a * x[threadIdx.x];
|
||||
}
|
||||
|
||||
__global__ void empty() {
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
const int kDataLen = 4;
|
||||
|
||||
float a = 2.0f;
|
||||
float host_x[kDataLen] = {1.0f, 2.0f, 3.0f, 4.0f};
|
||||
float host_y[kDataLen];
|
||||
|
||||
// Copy input data to device.
|
||||
float* device_x;
|
||||
float* device_y;
|
||||
|
||||
// CHECK: hipMalloc(&device_x, kDataLen * sizeof(float));
|
||||
cudaMalloc(&device_x, kDataLen * sizeof(float));
|
||||
|
||||
#ifdef HERRING
|
||||
// CHECK: hipMalloc(&device_y, kDataLen * sizeof(float));
|
||||
cudaMalloc(&device_y, kDataLen * sizeof(float));
|
||||
#else
|
||||
// CHECK: hipMalloc(&device_y, kDataLen * sizeof(double));
|
||||
cudaMalloc(&device_y, kDataLen * sizeof(double));
|
||||
#endif
|
||||
|
||||
// CHECK: hipMemcpy(device_x, host_x, kDataLen * sizeof(float), hipMemcpyHostToDevice);
|
||||
cudaMemcpy(device_x, host_x, kDataLen * sizeof(float), cudaMemcpyHostToDevice);
|
||||
|
||||
// Launch the kernel in numerous different strange ways to exercise the prerocessor.
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(axpy), dim3(1), dim3(kDataLen), 0, 0, a, device_x, device_y);
|
||||
axpy<<<1, kDataLen>>>(a, device_x, device_y);
|
||||
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(axpy<float>), dim3(1), dim3(kDataLen), 0, 0, a, device_x, device_y);
|
||||
axpy<float><<<1, kDataLen>>>(a, device_x, device_y);
|
||||
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(axpy<float>), dim3(1), dim3(kDataLen), 0, 0, a, TOKEN_PASTE(device, _x), device_y);
|
||||
axpy<float><<<1, kDataLen>>>(a, TOKEN_PASTE(device, _x), device_y);
|
||||
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(axpy<float>), dim3(1), dim3(kDataLen), 0, 0, ARG_LIST_AS_MACRO);
|
||||
axpy<float><<<1, kDataLen>>>(ARG_LIST_AS_MACRO);
|
||||
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(KERNEL_NAME_MACRO), dim3(1), dim3(kDataLen), 0, 0, ARG_LIST_AS_MACRO);
|
||||
KERNEL_NAME_MACRO<<<1, kDataLen>>>(ARG_LIST_AS_MACRO);
|
||||
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(axpy<float>), dim3(1), dim3(kDataLen), 0, 0, ARG_LIST_AS_MACRO);
|
||||
KERNEL_CALL_AS_MACRO(ARG_LIST_AS_MACRO);
|
||||
|
||||
// CHECK: hipLaunchKernelGGL(empty, dim3(1), dim3(kDataLen), 0, 0);
|
||||
empty<<<1, kDataLen>>> ( );
|
||||
|
||||
// CHECK: hipLaunchKernelGGL(empty, dim3(1), dim3(kDataLen), 0, 0);
|
||||
empty<<<1, kDataLen, 0>>>();
|
||||
|
||||
// CHECK: hipLaunchKernelGGL(empty, dim3(1), dim3(kDataLen), 0, 0);
|
||||
empty<<<1, kDataLen, 0, 0>>>();
|
||||
|
||||
// CHECK: COMPLETE_LAUNCH;
|
||||
COMPLETE_LAUNCH;
|
||||
|
||||
|
||||
// Copy output data to host.
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
// CHECK: hipMemcpy(host_y, device_y, kDataLen * sizeof(float), hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(host_y, device_y, kDataLen * sizeof(float), cudaMemcpyDeviceToHost);
|
||||
|
||||
// Print the results.
|
||||
for (int i = 0; i < kDataLen; ++i) {
|
||||
std::cout << "y[" << i << "] = " << host_y[i] << "\n";
|
||||
}
|
||||
|
||||
// CHECK: hipDeviceReset();
|
||||
cudaDeviceReset();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// To measure effects of memory coalescing. Coalescing.cu
|
||||
// B. Wilkinson Jan 30, 2011
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda.h>
|
||||
|
||||
#define BlockSize 16 // Size of blocks, 32 x 32 threads, fixed, used globally
|
||||
|
||||
__global__ void gpu_Comput (int *h, int N, int T) {
|
||||
|
||||
// Array loaded with global thread ID that acesses that location
|
||||
|
||||
int col = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
int row = threadIdx.y + blockDim.y * blockIdx.y;
|
||||
|
||||
int threadID = col + row * N;
|
||||
int index = row + col * N; // sequentially down each row
|
||||
|
||||
for (int t = 0; t < T; t++) // loop to repeat to reduce other time effects
|
||||
h[index] = threadID; // load array with flattened global thread ID
|
||||
}
|
||||
|
||||
void printArray(int *h, int N) {
|
||||
|
||||
printf("Results of computation, every N/8 numbers, eight numbers\n");
|
||||
|
||||
for (int row = 0; row < N; row += N/8) {
|
||||
for (int col = 0; col < N; col += N/8)
|
||||
printf("%6d ", h[col + row * N]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
int T = 100; // number of iterations, entered at keyboard
|
||||
int B = 1; // number of blocks, entered at keyboard
|
||||
char key;
|
||||
|
||||
int *h, *dev_h; // ptr to array holding numbers on host and device
|
||||
// CHECK: hipEvent_t start, stop;
|
||||
cudaEvent_t start, stop; // cuda events to measure time
|
||||
float elapsed_time_ms1;
|
||||
// CHECK: hipEventCreate( &start );
|
||||
// CHECK: hipEventCreate( &stop );
|
||||
cudaEventCreate( &start );
|
||||
cudaEventCreate( &stop );
|
||||
|
||||
/* ------------------------- Keyboard input -----------------------------------*/
|
||||
|
||||
do { // loop to repeat complete program
|
||||
|
||||
printf("Grid Structure 2-D grid, 2-D blocks\n");
|
||||
printf("Blocks fixed at 16 x 16 threads, 512 threads, max for compute cap. 1.x\n");
|
||||
printf("Enter number of blocks in grid, each dimension, currently %d\n",B);
|
||||
scanf("%d",&B);
|
||||
printf("Enter number of iterations, currently %d\n",T);
|
||||
scanf("%d",&T);
|
||||
|
||||
int N = B * BlockSize; // size of data array, given input data
|
||||
|
||||
printf("Array size (and total grid-block size) %d x %d\n", N, N);
|
||||
|
||||
dim3 Block(BlockSize, BlockSize); //Block structure, 32 x 32 max
|
||||
dim3 Grid(B, B); //Grid structure, B x B
|
||||
|
||||
/* ------------------------- Allocate Memory-----------------------------------*/
|
||||
|
||||
int size = N * N * sizeof(int); // number of bytes in total in array
|
||||
h = (int*) malloc(size); // Array on host
|
||||
// CHECK: hipMalloc((void**)&dev_h, size);
|
||||
cudaMalloc((void**)&dev_h, size); // allocate device memory
|
||||
|
||||
/* ------------------------- GPU Computation -----------------------------------*/
|
||||
|
||||
// CHECK: hipEventRecord( start, 0 );
|
||||
cudaEventRecord( start, 0 );
|
||||
// CHECK: hipLaunchKernelGGL(gpu_Comput, dim3(Grid), dim3(Block), 0, 0, dev_h, N, T);
|
||||
gpu_Comput<<< Grid, Block >>>(dev_h, N, T);
|
||||
// CHECK: hipEventRecord( stop, 0 );
|
||||
// CHECK: hipEventSynchronize( stop );
|
||||
// CHECK: hipEventElapsedTime( &elapsed_time_ms1, start, stop );
|
||||
cudaEventRecord( stop, 0 ); // instrument code to measue end time
|
||||
cudaEventSynchronize( stop ); // wait for all work done by threads
|
||||
cudaEventElapsedTime( &elapsed_time_ms1, start, stop );
|
||||
// CHECK: hipMemcpy(h,dev_h, size ,hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(h,dev_h, size ,cudaMemcpyDeviceToHost); //Get results to check
|
||||
|
||||
printArray(h,N);
|
||||
printf("\nTime to calculate results on GPU: %f ms.\n", elapsed_time_ms1);
|
||||
|
||||
/* -------------------------REPEAT PROGRAM INPUT-----------------------------------*/
|
||||
|
||||
printf("\nEnter c to repeat, return to terminate\n");
|
||||
|
||||
scanf("%c",&key);
|
||||
scanf("%c",&key);
|
||||
|
||||
} while (key == 'c'); // loop of complete program
|
||||
|
||||
/* -------------- clean up ---------------------------------------*/
|
||||
|
||||
free(h);
|
||||
// CHECK: hipFree(dev_h);
|
||||
cudaFree(dev_h);
|
||||
// CHECK: hipEventDestroy(start);
|
||||
// CHECK: hipEventDestroy(stop);
|
||||
cudaEventDestroy(start);
|
||||
cudaEventDestroy(stop);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
/*
|
||||
Copyright (c) 2015-2016 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<cuda.h>
|
||||
#include<cuda_runtime.h>
|
||||
#include<iostream>
|
||||
#include<stdio.h>
|
||||
#include<malloc.h>
|
||||
|
||||
#define LEN 1024
|
||||
#define SIZE LEN * sizeof(float)
|
||||
#define ITER 1024*1024
|
||||
|
||||
// CHECK: if(status != hipSuccess) {
|
||||
#define check(msg, status){ \
|
||||
if(status != cudaSuccess) { \
|
||||
printf("%s failed. \n", #msg); \
|
||||
} \
|
||||
}
|
||||
|
||||
__global__ void Inc1(float *Ad, float *Bd){
|
||||
int tx = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
if(tx < 1 ){
|
||||
for(int i=0;i<ITER;i++){
|
||||
Ad[tx] = Ad[tx] + 1.0f;
|
||||
for(int j=0;j<256;j++){
|
||||
Bd[tx] = Ad[tx];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__global__ void Inc2(float *Ad, float *Bd){
|
||||
int tx = threadIdx.x + blockIdx.x * blockDim.x;
|
||||
if(tx < 1024){
|
||||
for(int i=0;i<ITER;i++){
|
||||
Ad[tx] = Ad[tx] + 1.0f;
|
||||
for(int j=0;j<256;j++){
|
||||
Bd[tx] = Ad[tx];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
float *A, *Ad, *Bd;
|
||||
A = new float[LEN];
|
||||
for(int i=0;i<LEN;i++){
|
||||
A[i] = 0.0f;
|
||||
}
|
||||
|
||||
// CHECK: hipError_t status;
|
||||
cudaError_t status;
|
||||
|
||||
// CHECK: status = hipHostRegister(A, SIZE, hipHostRegisterMapped);
|
||||
status = cudaHostRegister(A, SIZE, cudaHostRegisterMapped);
|
||||
check("Registering A",status);
|
||||
|
||||
// CHECK: hipHostGetDevicePointer(&Ad, A, 0);
|
||||
cudaHostGetDevicePointer(&Ad, A, 0);
|
||||
|
||||
// CHECK: hipMalloc((void**) &Bd, SIZE);
|
||||
cudaMalloc((void**) &Bd, SIZE);
|
||||
dim3 dimGrid(LEN/512,1,1);
|
||||
dim3 dimBlock(512,1,1);
|
||||
|
||||
// CHECK: hipLaunchKernelGGL(Inc1, dim3(dimGrid), dim3(dimBlock), 0, 0, Ad, Bd);
|
||||
Inc1<<<dimGrid, dimBlock>>>(Ad, Bd);
|
||||
A[0] = -(ITER*1.0f);
|
||||
std::cout<<"Same cache line before completion: \t"<< A[0]<<std::endl;
|
||||
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
std::cout<<"Same cache line after completion: \t"<< A[0]<<std::endl;
|
||||
|
||||
for(int i=0;i<LEN;i++){
|
||||
A[i] = 0.0f;
|
||||
}
|
||||
|
||||
// CHECK: hipLaunchKernelGGL(Inc2, dim3(dimGrid), dim3(dimBlock), 0, 0, Ad, Bd);
|
||||
Inc2<<<dimGrid, dimBlock>>>(Ad, Bd);
|
||||
A[0] = -(ITER*1.0f);
|
||||
std::cout<<"Diff cache line before completion: \t"<<A[0]<<std::endl;
|
||||
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
cudaDeviceSynchronize();
|
||||
std::cout<<"Diff cache line after completion: \t"<<A[0]<<std::endl;
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// Taken from Jonathan Hui blog https://jhui.github.io/2017/03/06/CUDA
|
||||
|
||||
#include <stdio.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda.h>
|
||||
|
||||
__global__ void dynamicReverse(int *d, int n)
|
||||
{
|
||||
// Dynamic shared memory
|
||||
// CHECK-NOT: extern __shared__
|
||||
// CHECK: HIP_DYNAMIC_SHARED(int, s);
|
||||
extern __shared__ int s[];
|
||||
int t = threadIdx.x;
|
||||
int tr = n-t-1;
|
||||
s[t] = d[t];
|
||||
__syncthreads();
|
||||
d[t] = s[tr];
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const int n = 64;
|
||||
int a[n], r[n], d[n];
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
a[i] = i;
|
||||
r[i] = n-i-1;
|
||||
d[i] = 0;
|
||||
}
|
||||
|
||||
int *d_d;
|
||||
// CHECK: hipMalloc(&d_d, n * sizeof(int));
|
||||
cudaMalloc(&d_d, n * sizeof(int));
|
||||
// run version with dynamic shared memory
|
||||
// CHECK: hipMemcpy(d_d, a, n*sizeof(int), hipMemcpyHostToDevice);
|
||||
cudaMemcpy(d_d, a, n*sizeof(int), cudaMemcpyHostToDevice);
|
||||
// CHECK: hipLaunchKernelGGL(dynamicReverse, dim3(1), dim3(n), n*sizeof(int), 0, d_d, n);
|
||||
dynamicReverse<<<1,n,n*sizeof(int)>>>(d_d, n);
|
||||
// CHECK: hipMemcpy(d, d_d, n*sizeof(int), hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(d, d_d, n*sizeof(int), cudaMemcpyDeviceToHost);
|
||||
for (int i = 0; i < n; i++)
|
||||
if (d[i] != r[i]) printf("Error: d[%d]!=r[%d] (%d, %d)n", i, i, d[i], r[i]);
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda.h>
|
||||
|
||||
#define K_THREADS 64
|
||||
#define K_INDEX() ((gridDim.x * blockIdx.y + blockIdx.x) * blockDim.x + threadIdx.x)
|
||||
#define RND() ((rand() & 0x7FFF) / float(0x8000))
|
||||
#define ERRORCHECK() cErrorCheck(__FILE__, __LINE__)
|
||||
|
||||
// CHECK: hipEvent_t t##_start, t##_end; \
|
||||
// CHECK: hipEventCreate(&t##_start); \
|
||||
// CHECK: hipEventCreate(&t##_end);
|
||||
#define TIMER_CREATE(t) \
|
||||
cudaEvent_t t##_start, t##_end; \
|
||||
cudaEventCreate(&t##_start); \
|
||||
cudaEventCreate(&t##_end);
|
||||
|
||||
// CHECK: hipEventRecord(t##_start); \
|
||||
// CHECK: hipEventSynchronize(t##_start);
|
||||
#define TIMER_START(t) \
|
||||
cudaEventRecord(t##_start); \
|
||||
cudaEventSynchronize(t##_start); \
|
||||
|
||||
// CHECK: hipEventRecord(t##_start); \
|
||||
// CHECK: hipEventSynchronize(t##_start); \
|
||||
// CHECK: hipEventRecord(t##_end); \
|
||||
// CHECK: hipEventSynchronize(t##_end); \
|
||||
// CHECK: hipEventElapsedTime(&t, t##_start, t##_end);
|
||||
#define TIMER_END(t) \
|
||||
cudaEventRecord(t##_start); \
|
||||
cudaEventSynchronize(t##_start); \
|
||||
cudaEventRecord(t##_end); \
|
||||
cudaEventSynchronize(t##_end); \
|
||||
cudaEventElapsedTime(&t, t##_start, t##_end);
|
||||
|
||||
|
||||
inline void cErrorCheck(const char *file, int line) {
|
||||
// CHECK: hipDeviceSynchronize();
|
||||
// CHECK: hipError_t err = hipGetLastError();
|
||||
// CHECK: if (err != hipSuccess) {
|
||||
// CHECK: printf("Error: %s\n", hipGetErrorString(err));
|
||||
cudaThreadSynchronize();
|
||||
cudaError_t err = cudaGetLastError();
|
||||
if (err != cudaSuccess) {
|
||||
printf("Error: %s\n", cudaGetErrorString(err));
|
||||
printf(" @ %s: %d\n", file, line);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
inline dim3 K_GRID(int n, int threads = K_THREADS) {
|
||||
int blocks = (int)ceilf(sqrtf((float)n/threads));
|
||||
dim3 grid(blocks, blocks);
|
||||
return grid;
|
||||
}
|
||||
|
||||
typedef struct data {
|
||||
int n;
|
||||
float4 *r, *v, *f;
|
||||
} data;
|
||||
|
||||
data cpu, gpu;
|
||||
|
||||
#define N 20
|
||||
|
||||
__global__ void repulsion(data gpu);
|
||||
__global__ void integration(data gpu);
|
||||
|
||||
|
||||
int main() {
|
||||
printf("Cuda Test 1\n");
|
||||
|
||||
int count = 0;
|
||||
// CHECK: hipGetDeviceCount(&count);
|
||||
cudaGetDeviceCount(&count);
|
||||
printf(" %d CUDA devices found\n", count);
|
||||
if(!count) {
|
||||
::exit(EXIT_FAILURE);
|
||||
}
|
||||
// CHECK: hipFree(0);
|
||||
cudaFree(0);
|
||||
|
||||
cpu.n = N;
|
||||
|
||||
cpu.r = (float4*)malloc(N * sizeof(float4));
|
||||
cpu.v = (float4*)malloc(N * sizeof(float4));
|
||||
cpu.f = (float4*)malloc(N * sizeof(float4));
|
||||
|
||||
for(int i = 0; i < N; ++i) {
|
||||
cpu.v[i] = make_float4(0,0,0,0);
|
||||
cpu.r[i] = make_float4(RND(), RND(), RND(), 0);
|
||||
cpu.f[i] = make_float4(0,0.01,0,0);
|
||||
}
|
||||
|
||||
gpu = cpu;
|
||||
// CHECK: hipMalloc(&gpu.r, N * sizeof(float4));
|
||||
// CHECK: hipMalloc(&gpu.v, N * sizeof(float4));
|
||||
// CHECK: hipMalloc(&gpu.f, N * sizeof(float4));
|
||||
cudaMalloc(&gpu.r, N * sizeof(float4));
|
||||
cudaMalloc(&gpu.v, N * sizeof(float4));
|
||||
cudaMalloc(&gpu.f, N * sizeof(float4));
|
||||
// CHECK: hipMemcpy(gpu.r, cpu.r, cpu.n * sizeof(float4), hipMemcpyHostToDevice);
|
||||
// CHECK: hipMemcpy(gpu.v, cpu.v, cpu.n * sizeof(float4), hipMemcpyHostToDevice);
|
||||
// CHECK: hipMemcpy(gpu.f, cpu.f, cpu.n * sizeof(float4), hipMemcpyHostToDevice);
|
||||
cudaMemcpy(gpu.r, cpu.r, cpu.n * sizeof(float4), cudaMemcpyHostToDevice);
|
||||
cudaMemcpy(gpu.v, cpu.v, cpu.n * sizeof(float4), cudaMemcpyHostToDevice);
|
||||
cudaMemcpy(gpu.f, cpu.f, cpu.n * sizeof(float4), cudaMemcpyHostToDevice);
|
||||
|
||||
ERRORCHECK();
|
||||
float rep;
|
||||
TIMER_CREATE(rep);
|
||||
TIMER_START(rep);
|
||||
// CHECK: hipLaunchKernelGGL(integration, dim3(K_GRID(cpu.n)), dim3(K_THREADS), 0, 0, gpu);
|
||||
integration <<< K_GRID(cpu.n), K_THREADS >>>(gpu);
|
||||
|
||||
TIMER_END(rep);
|
||||
printf("Took: %f ms\n", rep);
|
||||
ERRORCHECK();
|
||||
// CHECK: hipMemcpy(cpu.r, gpu.r, cpu.n * sizeof(float4), hipMemcpyDeviceToHost);
|
||||
// CHECK: hipMemcpy(cpu.v, gpu.v, cpu.n * sizeof(float4), hipMemcpyDeviceToHost);
|
||||
// CHECK: hipMemcpy(cpu.f, gpu.f, cpu.n * sizeof(float4), hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(cpu.r, gpu.r, cpu.n * sizeof(float4), cudaMemcpyDeviceToHost);
|
||||
cudaMemcpy(cpu.v, gpu.v, cpu.n * sizeof(float4), cudaMemcpyDeviceToHost);
|
||||
cudaMemcpy(cpu.f, gpu.f, cpu.n * sizeof(float4), cudaMemcpyDeviceToHost);
|
||||
// CHECK: hipHostFree(cpu.r);
|
||||
// CHECK: hipHostFree(cpu.v);
|
||||
// CHECK: hipHostFree(cpu.f);
|
||||
cudaFreeHost(cpu.r);
|
||||
cudaFreeHost(cpu.v);
|
||||
cudaFreeHost(cpu.f);
|
||||
// CHECK: hipFree(gpu.r);
|
||||
// CHECK: hipFree(gpu.v);
|
||||
// CHECK: hipFree(gpu.f);
|
||||
cudaFree(gpu.r);
|
||||
cudaFree(gpu.v);
|
||||
cudaFree(gpu.f);
|
||||
// CHECK: hipDeviceReset();
|
||||
cudaDeviceReset();
|
||||
|
||||
printf("Results: \n");
|
||||
for(int i = 0; i < N; ++i) {
|
||||
printf("%f, %f, %f \n", cpu.r[i].x, cpu.r[i].y, cpu.r[i].z);
|
||||
}
|
||||
|
||||
printf("Ready...\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
__global__ void repulsion(data gpu) {
|
||||
int idx = K_INDEX();
|
||||
if(idx < N) {
|
||||
gpu.r[idx].x = 1;
|
||||
gpu.r[idx].y = 1;
|
||||
gpu.r[idx].z = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#define MULT4(v, s) v.x *= s; v.y *= s; v.z *= s; v.w *= s;
|
||||
#define ADD4(v1, v2) v1.x += v2.x; v1.y += v2.y; v1.z += v2.z; v1.w += v2.w;
|
||||
|
||||
__global__ void integration(data gpu) {
|
||||
int i = K_INDEX();
|
||||
if(i < N) {
|
||||
MULT4(gpu.f[i], 0.01);
|
||||
MULT4(gpu.v[i], 0.01);
|
||||
ADD4(gpu.v[i], gpu.f[i]);
|
||||
ADD4(gpu.r[i], gpu.v[i]);
|
||||
gpu.f[i] = make_float4(0,0,0,0);
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
/*
|
||||
Copyright (c) 2015-2016 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 <stdio.h>
|
||||
#include <cuda_runtime.h>
|
||||
|
||||
#define CHECK(cmd) \
|
||||
{\
|
||||
cudaError_t error = cmd;\
|
||||
if (error != cudaSuccess) { \
|
||||
fprintf(stderr, "error: '%s'(%d) at %s:%d\n", cudaGetErrorString(error), error,__FILE__, __LINE__); \
|
||||
exit(EXIT_FAILURE);\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Square each element in the array A and write to array C.
|
||||
*/
|
||||
template <typename T>
|
||||
__global__ void
|
||||
vector_square(T *C_d, const 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) {
|
||||
C_d[i] = A_d[i] * A_d[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
float *A_d, *C_d;
|
||||
float *A_h, *C_h;
|
||||
size_t N = 1000000;
|
||||
size_t Nbytes = N * sizeof(float);
|
||||
|
||||
// CHECK: hipDeviceProp_t props;
|
||||
cudaDeviceProp props;
|
||||
|
||||
// CHECK: CHECK(hipGetDeviceProperties(&props, 0/*deviceID*/));
|
||||
CHECK(cudaGetDeviceProperties(&props, 0/*deviceID*/));
|
||||
printf ("info: running on device %s\n", props.name);
|
||||
|
||||
printf ("info: allocate host mem (%6.2f MB)\n", 2*Nbytes/1024.0/1024.0);
|
||||
A_h = (float*)malloc(Nbytes);
|
||||
|
||||
// CHECK: CHECK(A_h == 0 ? hipErrorOutOfMemory : hipSuccess );
|
||||
CHECK(A_h == 0 ? cudaErrorMemoryAllocation : cudaSuccess );
|
||||
C_h = (float*)malloc(Nbytes);
|
||||
|
||||
// CHECK: CHECK(C_h == 0 ? hipErrorOutOfMemory : hipSuccess );
|
||||
CHECK(C_h == 0 ? cudaErrorMemoryAllocation : cudaSuccess );
|
||||
// Fill with Phi + i
|
||||
for (size_t i=0; i<N; i++)
|
||||
{
|
||||
A_h[i] = 1.618f + i;
|
||||
}
|
||||
|
||||
printf ("info: allocate device mem (%6.2f MB)\n", 2*Nbytes/1024.0/1024.0);
|
||||
// CHECK: CHECK(hipMalloc(&A_d, Nbytes));
|
||||
// CHECK: CHECK(hipMalloc(&C_d, Nbytes));
|
||||
CHECK(cudaMalloc(&A_d, Nbytes));
|
||||
CHECK(cudaMalloc(&C_d, Nbytes));
|
||||
|
||||
|
||||
printf ("info: copy Host2Device\n");
|
||||
// CHECK: CHECK ( hipMemcpy(A_d, A_h, Nbytes, hipMemcpyHostToDevice));
|
||||
CHECK ( cudaMemcpy(A_d, A_h, Nbytes, cudaMemcpyHostToDevice));
|
||||
|
||||
const unsigned blocks = 512;
|
||||
const unsigned threadsPerBlock = 256;
|
||||
|
||||
printf ("info: launch 'vector_square' kernel\n");
|
||||
// CHECK: hipLaunchKernelGGL(HIP_KERNEL_NAME(vector_square), dim3(blocks), dim3(threadsPerBlock), 0, 0, C_d, A_d, N);
|
||||
vector_square <<<blocks, threadsPerBlock>>> (C_d, A_d, N);
|
||||
|
||||
printf ("info: copy Device2Host\n");
|
||||
// CHECK: CHECK ( hipMemcpy(C_h, C_d, Nbytes, hipMemcpyDeviceToHost));
|
||||
CHECK ( cudaMemcpy(C_h, C_d, Nbytes, cudaMemcpyDeviceToHost));
|
||||
|
||||
printf ("info: check result\n");
|
||||
for (size_t i=0; i<N; i++) {
|
||||
if (C_h[i] != A_h[i] * A_h[i]) {
|
||||
// CHECK: CHECK(hipErrorUnknown);
|
||||
CHECK(cudaErrorUnknown);
|
||||
}
|
||||
}
|
||||
printf ("PASSED!\n");
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// Taken from Jonathan Hui blog https://jhui.github.io/2017/03/06/CUDA
|
||||
|
||||
#include <stdio.h>
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <cuda.h>
|
||||
|
||||
__global__ void staticReverse(int *d, int n)
|
||||
{
|
||||
// CHECK-NOT: HIP_DYNAMIC_SHARED(int, s);
|
||||
// CHECK: __shared__ int s[64];
|
||||
__shared__ int s[64];
|
||||
int t = threadIdx.x;
|
||||
int tr = n-t-1;
|
||||
s[t] = d[t];
|
||||
// Will not conttinue until all threads completed.
|
||||
__syncthreads();
|
||||
d[t] = s[tr];
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const int n = 64;
|
||||
int a[n], r[n], d[n];
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
a[i] = i;
|
||||
r[i] = n-i-1;
|
||||
d[i] = 0;
|
||||
}
|
||||
|
||||
int *d_d;
|
||||
// CHECK: hipMalloc(&d_d, n * sizeof(int));
|
||||
cudaMalloc(&d_d, n * sizeof(int));
|
||||
// run version with static shared memory
|
||||
// CHECK: hipMemcpy(d_d, a, n*sizeof(int), hipMemcpyHostToDevice);
|
||||
cudaMemcpy(d_d, a, n*sizeof(int), cudaMemcpyHostToDevice);
|
||||
// CHECK: hipLaunchKernelGGL(staticReverse, dim3(1), dim3(n), 0, 0, d_d, n);
|
||||
staticReverse<<<1,n>>>(d_d, n);
|
||||
// CHECK: hipMemcpy(d, d_d, n*sizeof(int), hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(d, d_d, n*sizeof(int), cudaMemcpyDeviceToHost);
|
||||
for (int i = 0; i < n; i++)
|
||||
if (d[i] != r[i]) printf("Error: d[%d]!=r[%d] (%d, %d)n", i, i, d[i], r[i]);
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
// RUN: %run_test hipify "%s" "%t" %hipify_args %clang_args
|
||||
|
||||
// Kernel definition
|
||||
__global__ void vecAdd(float* A, float* B, float* C)
|
||||
{
|
||||
int i = threadIdx.x;
|
||||
A[i] = 0;
|
||||
B[i] = i;
|
||||
C[i] = A[i] + B[i];
|
||||
}
|
||||
// CHECK: #include <hip/hip_runtime.h>
|
||||
#include <stdio.h>
|
||||
#define SIZE 10
|
||||
#define KERNELINVOKES 5000000
|
||||
int vecadd(int gpudevice, int rank)
|
||||
{
|
||||
int devcheck(int, int);
|
||||
devcheck(gpudevice, rank);
|
||||
float A[SIZE], B[SIZE], C[SIZE];
|
||||
// Kernel invocation
|
||||
float *devPtrA;
|
||||
float *devPtrB;
|
||||
float *devPtrC;
|
||||
int memsize = SIZE * sizeof(float);
|
||||
// CHECK: hipMalloc((void**)&devPtrA, memsize);
|
||||
// CHECK: hipMalloc((void**)&devPtrB, memsize);
|
||||
// CHECK: hipMalloc((void**)&devPtrC, memsize);
|
||||
cudaMalloc((void**)&devPtrA, memsize);
|
||||
cudaMalloc((void**)&devPtrB, memsize);
|
||||
cudaMalloc((void**)&devPtrC, memsize);
|
||||
// CHECK: hipMemcpy(devPtrA, A, memsize, hipMemcpyHostToDevice);
|
||||
// CHECK: hipMemcpy(devPtrB, B, memsize, hipMemcpyHostToDevice);
|
||||
cudaMemcpy(devPtrA, A, memsize, cudaMemcpyHostToDevice);
|
||||
cudaMemcpy(devPtrB, B, memsize, cudaMemcpyHostToDevice);
|
||||
for (int i = 0; i<KERNELINVOKES; i++)
|
||||
{
|
||||
// CHECK: hipLaunchKernelGGL(vecAdd, dim3(1), dim3(gpudevice), 0, 0, devPtrA, devPtrB, devPtrC);
|
||||
vecAdd <<< 1, gpudevice >>>(devPtrA, devPtrB, devPtrC);
|
||||
}
|
||||
// CHECK: hipMemcpy(C, devPtrC, memsize, hipMemcpyDeviceToHost);
|
||||
cudaMemcpy(C, devPtrC, memsize, cudaMemcpyDeviceToHost);
|
||||
// calculate only up to gpudevice to show the unique output
|
||||
// of each rank's kernel launch
|
||||
for (int i = 0; i<gpudevice; i++)
|
||||
printf("rank %d: C[%d]=%f\n", rank, i, C[i]);
|
||||
// CHECK: hipFree(devPtrA);
|
||||
// CHECK: hipFree(devPtrA);
|
||||
// CHECK: hipFree(devPtrA);
|
||||
cudaFree(devPtrA);
|
||||
cudaFree(devPtrA);
|
||||
cudaFree(devPtrA);
|
||||
}
|
||||
int devcheck(int gpudevice, int rank)
|
||||
{
|
||||
int device_count = 0;
|
||||
int device; // used with cudaGetDevice() to verify cudaSetDevice()
|
||||
// CHECK: hipGetDeviceCount(&device_count);
|
||||
cudaGetDeviceCount(&device_count);
|
||||
if (gpudevice >= device_count)
|
||||
{
|
||||
printf("gpudevice >= device_count ... exiting\n");
|
||||
exit(1);
|
||||
}
|
||||
// CHECK: hipError_t cudareturn;
|
||||
// CHECK: hipDeviceProp_t deviceProp;
|
||||
// CHECK: hipGetDeviceProperties(&deviceProp, gpudevice);
|
||||
cudaError_t cudareturn;
|
||||
cudaDeviceProp deviceProp;
|
||||
cudaGetDeviceProperties(&deviceProp, gpudevice);
|
||||
if (deviceProp.warpSize <= 1)
|
||||
{
|
||||
printf("rank %d: warning, CUDA Device Emulation (CPU) detected, exiting\n", rank);
|
||||
exit(1);
|
||||
}
|
||||
// CHECK: cudareturn = hipSetDevice(gpudevice);
|
||||
cudareturn = cudaSetDevice(gpudevice);
|
||||
// CHECK: if (cudareturn == hipErrorInvalidDevice)
|
||||
if (cudareturn == cudaErrorInvalidDevice)
|
||||
{
|
||||
// CHECK: perror("hipSetDevice returned hipErrorInvalidDevice");
|
||||
perror("cudaSetDevice returned cudaErrorInvalidDevice");
|
||||
}
|
||||
else
|
||||
{
|
||||
// CHECK: hipGetDevice(&device);
|
||||
cudaGetDevice(&device);
|
||||
printf("rank %d: cudaGetDevice()=%d\n", rank, device);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user