From 624b2f35ffdc09fc757a63a8be59f336266439ef Mon Sep 17 00:00:00 2001 From: Ben Sander Date: Wed, 13 Apr 2016 17:32:38 -0500 Subject: [PATCH] add hcc dialects sample --- samples/0_Intro/hcc_dialects/Makefile | 66 +++++++++++++++++++ .../hcc_dialects/vadd_amp_arrayview.cpp | 48 ++++++++++++++ samples/0_Intro/hcc_dialects/vadd_hc_am.cpp | 59 +++++++++++++++++ .../0_Intro/hcc_dialects/vadd_hc_array.cpp | 53 +++++++++++++++ samples/0_Intro/hcc_dialects/vadd_hc_array.hc | 33 ++++++++++ .../hcc_dialects/vadd_hc_arrayview.cpp | 48 ++++++++++++++ samples/0_Intro/hcc_dialects/vadd_hip.cpp | 51 ++++++++++++++ 7 files changed, 358 insertions(+) create mode 100644 samples/0_Intro/hcc_dialects/Makefile create mode 100644 samples/0_Intro/hcc_dialects/vadd_amp_arrayview.cpp create mode 100644 samples/0_Intro/hcc_dialects/vadd_hc_am.cpp create mode 100644 samples/0_Intro/hcc_dialects/vadd_hc_array.cpp create mode 100644 samples/0_Intro/hcc_dialects/vadd_hc_array.hc create mode 100644 samples/0_Intro/hcc_dialects/vadd_hc_arrayview.cpp create mode 100644 samples/0_Intro/hcc_dialects/vadd_hip.cpp diff --git a/samples/0_Intro/hcc_dialects/Makefile b/samples/0_Intro/hcc_dialects/Makefile new file mode 100644 index 0000000000..108d30201c --- /dev/null +++ b/samples/0_Intro/hcc_dialects/Makefile @@ -0,0 +1,66 @@ +HCC_HOME?=/opt/rocm/hcc +HCC = $(HCC_HOME)/bin/hcc + +HCC_CFLAGS= `$(HCC_HOME)/bin/hcc-config --cxxflags` +HCC_LDFLAGS= `$(HCC_HOME)/bin/hcc-config --ldflags` + +CPPAMP_CFLAGS= -std=c++amp -stdlib=libc++ -I/opt/hcc/include +CPPAMP_LDFLAGS= -std=c++amp -L/opt/hcc/lib -Wl,--rpath=/opt/hcc/lib -lc++ -lc++abi -ldl -lpthread -Wl,--whole-archive -lmcwamp -Wl,--no-whole-archive + +HIP_PATH?=/opt/rocm/hip +HIPCC=$(HIP_PATH)/bin/hipcc +HIP_PLATFORM=$(shell $(HIP_PATH)/bin/hipconfig --platform) + +ifneq (${HIP_PLATFORM}, hcc) +$(error hcc_dialects requires hcc compiler and only runs on hcc platform) +endif + + +TARGETS=vadd_hc_arrayview vadd_hc_array vadd_amp_arrayview vadd_hip + +all: $(TARGETS) + +clean: + rm -f $(TARGETS) *.o + +run: $(TARGETS) + @for t in $(TARGETS); do\ + echo "Running $$t"; \ + ./$$t; \ + done + + +# HCC version: +vadd_hc_arrayview.o: vadd_hc_arrayview.cpp + $(HCC) $(HCC_CFLAGS) -c $< -o $@ +vadd_hc_arrayview: vadd_hc_arrayview.o + $(HCC) $(HCC_LDFLAGS) $< -o $@ + + +# HCC version, using explicit arrays: +vadd_hc_array.o: vadd_hc_array.cpp + $(HCC) $(HCC_CFLAGS) -c $< -o $@ +vadd_hc_array: vadd_hc_array.o + $(HCC) $(HCC_LDFLAGS) $< -o $@ + + +# HCC version, using AM (accelerator memory) pointer +vadd_hc_am.o: vadd_hc_am.cpp + $(HCC) $(HCC_CFLAGS) -c $< -o $@ +vadd_hc_am: vadd_hc_am.o + $(HCC) $(HCC_LDFLAGS) $< -o $@ + + + +# HIP version: +vadd_hip.o: vadd_hip.cpp + $(HIPCC) -c $< -o $@ +vadd_hip: vadd_hip.o + $(HIPCC) $< -o $@ + + +# AMP version: +vadd_amp_arrayview.o: vadd_amp_arrayview.cpp + $(HCC) $(CPPAMP_CFLAGS) -c $< -o $@ +vadd_amp_arrayview: vadd_amp_arrayview.o + $(HCC) $(CPPAMP_LDFLAGS) $< -o $@ diff --git a/samples/0_Intro/hcc_dialects/vadd_amp_arrayview.cpp b/samples/0_Intro/hcc_dialects/vadd_amp_arrayview.cpp new file mode 100644 index 0000000000..6fdea5d830 --- /dev/null +++ b/samples/0_Intro/hcc_dialects/vadd_amp_arrayview.cpp @@ -0,0 +1,48 @@ +// Simple test showing how to use C++AMP syntax with array_view. +// The code uses AMP's array_view class, which provides automatic data synchronization +// of data between the host and the accelerator. As noted below, the HCC runtime +// will automatically copy data to and from the host, without the user needing +// to manually perform such copies. This is an excellent mode for developers +// new to GPU programming and matches the memory models provided by recent systems where +// CPU and GPU share the same memory pool. Advanced programmers may prefer +// more explicit control over the data movement - shown in the other vadd_hc_array and +// vadd_hc_am examples. +// This example shows the similarity between C++AMP and and HC for simple cases where +// implicit data transfer is used - really the only difference is the namespace. +// Other examples show some of the more advanced controls. + +#include + +int main(int argc, char *argv[]) +{ + int sizeElements = 1000000; + + // Allocate auto-managed host/device views of data: + concurrency::array_view A(sizeElements); + concurrency::array_view B(sizeElements); + concurrency::array_view C(sizeElements); + + // Initialize host data + for (int i=0; i (sizeElements), + [=] (concurrency::index<1> idx) restrict(amp) { + int i = idx[0]; + C[i] = A[i] + B[i]; + }); + + for (int i=0; i +#include + +int main(int argc, char *argv[]) +{ + int sizeElements = 1000000; + size_t sizeBytes = sizeElements * sizeof(float); + + // Allocate host memory + float *A_h = (float*)malloc(sizeBytes); + float *B_h = (float*)malloc(sizeBytes); + float *C_h = (float*)malloc(sizeBytes); + + // Allocate device pointers: + // Unlike array_view, these must be explicitly managed by user: + hc::accelerator acc; // grab default accelerator where we want to allocate memory: + hc::accelerator_view av = acc.get_default_view(); + + float *A_d, *B_d, *C_d; + A_d = hc::am_alloc(sizeBytes, acc, 0); + B_d = hc::am_alloc(sizeBytes, acc, 0); + C_d = hc::am_alloc(sizeBytes, acc, 0); + + // Initialize host data + for (int i=0; i (sizeElements), + [&] (hc::index<1> idx) [[hc]] { + int i = idx[0]; + C_d[i] = A_d[i] + B_d[i]; + }); + + + // This copy is in same AV as the kernel and thus will wait for the kernel to finish before executing. + av.copy(C_d, C_h); // C++ copy D2H + + + for (int i=0; i + +int main(int argc, char *argv[]) +{ + int sizeElements = 1000000; + size_t sizeBytes = sizeElements * sizeof(float); + + // Allocate host memory + float *A_h = (float*)malloc(sizeBytes); + float *B_h = (float*)malloc(sizeBytes); + float *C_h = (float*)malloc(sizeBytes); + + // Allocate device arrays<> + // Unlike array_view, these must be explicitly managed by user: + hc::array A_d(sizeElements); + hc::array B_d(sizeElements); + hc::array C_d(sizeElements); + + // Initialize host data + for (int i=0; i types are not implicitly copied, so we performed copies above. + hc::parallel_for_each(hc::extent<1> (sizeElements), + [&] (hc::index<1> idx) [[hc]] { + int i = idx[0]; + C_d[i] = A_d[i] + B_d[i]; + }); + + // HCC runtime knows that C_d depends on previous PFE and will force the copy to wait for the PFE to complte. + hc::copy(C_d, C_h); // C++ copy D2H + + + for (int i=0; i + +int main(int argc, char *argv[]) +{ + int size = 1000000; + + // Allocate auto-managed host/device views of data: + hc::array_view A(size); + hc::array_view B(size); + hc::array_view C(size); + + // Initialize host data + for (int i=0; i (size), + [=] (hc::index<1> idx) [[hc]] { + int i = idx[0]; + C[i] = A[i] + B[i]; + }); + + for (int i=0; i + +int main(int argc, char *argv[]) +{ + int sizeElements = 1000000; + + // Allocate auto-managed host/device views of data: + hc::array_view A(sizeElements); + hc::array_view B(sizeElements); + hc::array_view C(sizeElements); + + // Initialize host data + for (int i=0; i (sizeElements), + [=] (hc::index<1> idx) [[hc]] { + int i = idx[0]; + C[i] = A[i] + B[i]; + }); + + for (int i=0; i + +__global__ void vadd_hip(hipLaunchParm lp, const float *a, const float *b, float *c, int N) +{ + int idx = (hipBlockIdx_x * hipBlockDim_x + hipThreadIdx_x); + + if (idx < N) { + c[idx] = a[idx] + b[idx]; + } +} + + +int main(int argc, char *argv[]) +{ + int sizeElements = 1000000; + size_t sizeBytes = sizeElements * sizeof(float); + + // Allocate host memory + float *A_h = (float*)malloc(sizeBytes); + float *B_h = (float*)malloc(sizeBytes); + float *C_h = (float*)malloc(sizeBytes); + + // Allocate device memory: + float *A_d, *B_d, *C_d; + hipMalloc(&A_d, sizeBytes); + hipMalloc(&B_d, sizeBytes); + hipMalloc(&C_d, sizeBytes); + + // Initialize host data + for (int i=0; i