From 74f38a57fd3693e7b41cec02dfefa1f1da386692 Mon Sep 17 00:00:00 2001 From: LaurelinTheGold Date: Sun, 19 Sep 2021 23:01:34 -0400 Subject: [PATCH 1/9] CPU done --- stream_compaction/cpu.cu | 65 ++++++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/stream_compaction/cpu.cu b/stream_compaction/cpu.cu index 719fa11..c9d1760 100644 --- a/stream_compaction/cpu.cu +++ b/stream_compaction/cpu.cu @@ -3,10 +3,12 @@ #include "common.h" -namespace StreamCompaction { - namespace CPU { +namespace StreamCompaction +{ + namespace CPU + { using StreamCompaction::Common::PerformanceTimer; - PerformanceTimer& timer() + PerformanceTimer &timer() { static PerformanceTimer timer; return timer; @@ -17,9 +19,16 @@ namespace StreamCompaction { * For performance analysis, this is supposed to be a simple for loop. * (Optional) For better understanding before starting moving to GPU, you can simulate your GPU scan in this function first. */ - void scan(int n, int *odata, const int *idata) { + void scan(int n, int *odata, const int *idata) + { timer().startCpuTimer(); // TODO + int tmpAcc = 0; + for (int i = 0; i < n; i++) + { + odata[i] = tmpAcc; + tmpAcc += idata[i]; + } timer().endCpuTimer(); } @@ -28,11 +37,21 @@ namespace StreamCompaction { * * @returns the number of elements remaining after compaction. */ - int compactWithoutScan(int n, int *odata, const int *idata) { + int compactWithoutScan(int n, int *odata, const int *idata) + { timer().startCpuTimer(); // TODO + int curIdx = 0; + for (int i = 0; i < n; i++) + { + if (idata[i] != 0) + { + odata[curIdx] = idata[i]; + curIdx++; + } + } timer().endCpuTimer(); - return -1; + return curIdx; } /** @@ -40,11 +59,39 @@ namespace StreamCompaction { * * @returns the number of elements remaining after compaction. */ - int compactWithScan(int n, int *odata, const int *idata) { + int compactWithScan(int n, int *odata, const int *idata) + { + int *tmpData = new int[n]; + int *tmpData2 = new int[n]; timer().startCpuTimer(); - // TODO + // map + for (int i = 0; i < n; i++) + { + tmpData[i] = idata[i] != 0; + } + // scan + int tmpAcc = 0; + for (int i = 0; i < n; i++) + { + tmpData2[i] = tmpAcc; + tmpAcc += tmpData[i]; + } + int const *arrPtr = idata; + // if last elem of mapped boolarr is 0, tmpData[n-1] is 0 + int retVal = tmpData2[n - 1] + tmpData[n - 1]; + for (int i = 0; i < retVal; i++) + { + while (*arrPtr == 0) + { + arrPtr++; + } + odata[i] = *arrPtr; + arrPtr++; + } timer().endCpuTimer(); - return -1; + delete tmpData2; + delete tmpData; + return retVal; } } } From 9d058ebe6f2dd45c022856766825a8eed9993bad Mon Sep 17 00:00:00 2001 From: LaurelinTheGold Date: Mon, 20 Sep 2021 01:03:00 -0400 Subject: [PATCH 2/9] Naive scan works i think --- .vscode/settings.json | 7 ++++ stream_compaction/common.h | 47 +++++++++++++++++++-------- stream_compaction/cpu.cu | 4 +-- stream_compaction/naive.cu | 65 +++++++++++++++++++++++++++++++++++--- 4 files changed, 102 insertions(+), 21 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..51e5ae4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "charconv": "cpp", + "xstring": "cpp", + "xtree": "cpp" + } +} \ No newline at end of file diff --git a/stream_compaction/common.h b/stream_compaction/common.h index d2c1fed..a35ad3b 100644 --- a/stream_compaction/common.h +++ b/stream_compaction/common.h @@ -10,6 +10,8 @@ #include #include +#define blockSize 512 + #define FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) #define checkCUDAError(msg) checkCUDAErrorFn(msg, FILENAME, __LINE__) @@ -18,24 +20,29 @@ */ void checkCUDAErrorFn(const char *msg, const char *file = NULL, int line = -1); -inline int ilog2(int x) { +inline int ilog2(int x) +{ int lg = 0; - while (x >>= 1) { + while (x >>= 1) + { ++lg; } return lg; } -inline int ilog2ceil(int x) { +inline int ilog2ceil(int x) +{ return x == 1 ? 0 : ilog2(x - 1) + 1; } -namespace StreamCompaction { - namespace Common { +namespace StreamCompaction +{ + namespace Common + { __global__ void kernMapToBoolean(int n, int *bools, const int *idata); __global__ void kernScatter(int n, int *odata, - const int *idata, const int *bools, const int *indices); + const int *idata, const int *bools, const int *indices); /** * This class is used for timing the performance @@ -60,7 +67,10 @@ namespace StreamCompaction { void startCpuTimer() { - if (cpu_timer_started) { throw std::runtime_error("CPU timer already started"); } + if (cpu_timer_started) + { + throw std::runtime_error("CPU timer already started"); + } cpu_timer_started = true; time_start_cpu = std::chrono::high_resolution_clock::now(); @@ -70,7 +80,10 @@ namespace StreamCompaction { { time_end_cpu = std::chrono::high_resolution_clock::now(); - if (!cpu_timer_started) { throw std::runtime_error("CPU timer not started"); } + if (!cpu_timer_started) + { + throw std::runtime_error("CPU timer not started"); + } std::chrono::duration duro = time_end_cpu - time_start_cpu; prev_elapsed_time_cpu_milliseconds = @@ -81,7 +94,10 @@ namespace StreamCompaction { void startGpuTimer() { - if (gpu_timer_started) { throw std::runtime_error("GPU timer already started"); } + if (gpu_timer_started) + { + throw std::runtime_error("GPU timer already started"); + } gpu_timer_started = true; cudaEventRecord(event_start); @@ -92,7 +108,10 @@ namespace StreamCompaction { cudaEventRecord(event_end); cudaEventSynchronize(event_end); - if (!gpu_timer_started) { throw std::runtime_error("GPU timer not started"); } + if (!gpu_timer_started) + { + throw std::runtime_error("GPU timer not started"); + } cudaEventElapsedTime(&prev_elapsed_time_gpu_milliseconds, event_start, event_end); gpu_timer_started = false; @@ -109,10 +128,10 @@ namespace StreamCompaction { } // remove copy and move functions - PerformanceTimer(const PerformanceTimer&) = delete; - PerformanceTimer(PerformanceTimer&&) = delete; - PerformanceTimer& operator=(const PerformanceTimer&) = delete; - PerformanceTimer& operator=(PerformanceTimer&&) = delete; + PerformanceTimer(const PerformanceTimer &) = delete; + PerformanceTimer(PerformanceTimer &&) = delete; + PerformanceTimer &operator=(const PerformanceTimer &) = delete; + PerformanceTimer &operator=(PerformanceTimer &&) = delete; private: cudaEvent_t event_start = nullptr; diff --git a/stream_compaction/cpu.cu b/stream_compaction/cpu.cu index c9d1760..47fc827 100644 --- a/stream_compaction/cpu.cu +++ b/stream_compaction/cpu.cu @@ -89,8 +89,8 @@ namespace StreamCompaction arrPtr++; } timer().endCpuTimer(); - delete tmpData2; - delete tmpData; + delete[] tmpData2; + delete[] tmpData; return retVal; } } diff --git a/stream_compaction/naive.cu b/stream_compaction/naive.cu index 4308876..a22d855 100644 --- a/stream_compaction/naive.cu +++ b/stream_compaction/naive.cu @@ -3,23 +3,78 @@ #include "common.h" #include "naive.h" -namespace StreamCompaction { - namespace Naive { +#define checkCUDAErrorWithLine(msg) checkCUDAError(msg, __LINE__) + +namespace StreamCompaction +{ + namespace Naive + { using StreamCompaction::Common::PerformanceTimer; - PerformanceTimer& timer() + PerformanceTimer &timer() { static PerformanceTimer timer; return timer; } - // TODO: __global__ + __global__ void kernScan(int n, int layer, int *odata, const int *idata) + { + int index = (blockIdx.x * blockDim.x) + threadIdx.x; + if (index >= n) + { + return; + } + int offset = pow(2, layer); + int tmp = idata[index]; + odata[index] = index < offset ? tmp : tmp + idata[index - offset]; + } /** * Performs prefix-sum (aka scan) on idata, storing the result into odata. */ - void scan(int n, int *odata, const int *idata) { + void scan(int n, int *odata, const int *idata) + { + int power = ilog2ceil(n); + int size = pow(2, power); + dim3 fullBlocksPerGrid((size + blockSize - 1) / blockSize); + int *bufA; // = new int[size]; + int *bufB; // = new int[size]; + cudaMalloc((void **)&bufA, size * sizeof(int)); + checkCUDAErrorWithLine("cudaMalloc bufA failed!"); + cudaMalloc((void **)&bufB, size * sizeof(int)); + checkCUDAErrorWithLine("cudaMalloc bufB failed!"); + + // std::fill(bufA, bufA + size, 0); + // std::fill(bufB, bufB + size, 0); + cudaMemset(bufA, 0, size * sizeof(int)); + cudaMemset(bufB, 0, size * sizeof(int)); + // std::copy(idata, idata + n, bufA + size - n); + cudaMemcpy(bufA + size - n, idata, n * sizeof(int), cudaMemcpyHostToDevice); + int *tmp; timer().startGpuTimer(); // TODO + for (int layer = 0; layer < power; layer++) + { + // invoke kernel + kernScan<<>>(size, layer, bufB, bufA); + cudaDeviceSynchronize(); + // swap bufA and bufB + tmp = bufA; + bufA = bufB; + bufB = tmp; + } + cudaDeviceSynchronize(); timer().endGpuTimer(); + int *tmpArr = new int[n]; + cudaMemcpy(tmpArr, bufA + size - n, n * sizeof(int), cudaMemcpyDeviceToHost); + odata[0] = 0; + for (int i = 1; i < n; i++) + { + odata[i] = tmpArr[i - 1]; + } + delete[] tmpArr; + cudaFree(bufA); + checkCUDAErrorWithLine("cudaFree bufA failed!"); + cudaFree(bufB); + checkCUDAErrorWithLine("cudaFree bufB failed!"); } } } From 6456f60b1f313735b45af086bf35968033ba54ee Mon Sep 17 00:00:00 2001 From: LaurelinTheGold Date: Tue, 21 Sep 2021 13:42:53 -0400 Subject: [PATCH 3/9] upsweep ougght to work --- .vscode/settings.json | 3 ++- stream_compaction/common.h | 4 ++- stream_compaction/efficient.cu | 48 ++++++++++++++++++++++++++++++---- stream_compaction/naive.cu | 27 +++++++------------ 4 files changed, 57 insertions(+), 25 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 51e5ae4..09da644 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,7 @@ "files.associations": { "charconv": "cpp", "xstring": "cpp", - "xtree": "cpp" + "xtree": "cpp", + "chrono": "cpp" } } \ No newline at end of file diff --git a/stream_compaction/common.h b/stream_compaction/common.h index a35ad3b..d3e3e7a 100644 --- a/stream_compaction/common.h +++ b/stream_compaction/common.h @@ -10,11 +10,13 @@ #include #include -#define blockSize 512 +#define blockSize 256 #define FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) #define checkCUDAError(msg) checkCUDAErrorFn(msg, FILENAME, __LINE__) +#define checkCUDAErrorWithLine(msg) checkCUDAError(msg, __LINE__) + /** * Check for CUDA errors; print and exit if there was a problem. */ diff --git a/stream_compaction/efficient.cu b/stream_compaction/efficient.cu index 2db346e..4ab8e69 100644 --- a/stream_compaction/efficient.cu +++ b/stream_compaction/efficient.cu @@ -3,22 +3,59 @@ #include "common.h" #include "efficient.h" -namespace StreamCompaction { - namespace Efficient { +namespace StreamCompaction +{ + namespace Efficient + { using StreamCompaction::Common::PerformanceTimer; - PerformanceTimer& timer() + PerformanceTimer &timer() { static PerformanceTimer timer; return timer; } + __global__ void kernScanEfficientUpSweep(int n, int layer, int *data) + { + int index = (blockIdx.x * blockDim.x) + threadIdx.x; + if (index >= n) + { + return; + } + int shift = pow(2, layer); + int otherVal = (index & ((1 << layer) - 1) == 0 ? 1 : 0) * + data[index - shift]; + __syncthreads(); + data[index] += otherVal; + } + /** * Performs prefix-sum (aka scan) on idata, storing the result into odata. */ - void scan(int n, int *odata, const int *idata) { + void scan(int n, int *odata, const int *idata) + { + //next power of 2 + int power = ilog2ceil(n); + int size = pow(2, power); + int offset = size - n; + dim3 fullBlocksPerGrid((size + blockSize - 1) / blockSize); + int *buf; + cudaMalloc((void **)&buf, size * sizeof(int)); + checkCUDAErrorWithLine("cudaMalloc buf failed!"); + cudaMemset(buf, 0, size * sizeof(int)); + cudaMemcpy(buf + offset, idata, n * sizeof(int), cudaMemcpyHostToDevice); timer().startGpuTimer(); // TODO + for (int layer = 0; layer < power; layer++) + { + // invoke kernel + kernScanEfficientUpSweep<<>>(size, layer, buf); + cudaDeviceSynchronize(); + } timer().endGpuTimer(); + cudaMemcpy(odata + 1, buf + offset, (n - 1) * sizeof(int), cudaMemcpyDeviceToHost); + odata[0] = 0; + cudaFree(buf); + checkCUDAErrorWithLine("cudaFree buf failed!"); } /** @@ -30,7 +67,8 @@ namespace StreamCompaction { * @param idata The array of elements to compact. * @returns The number of elements remaining after compaction. */ - int compact(int n, int *odata, const int *idata) { + int compact(int n, int *odata, const int *idata) + { timer().startGpuTimer(); // TODO timer().endGpuTimer(); diff --git a/stream_compaction/naive.cu b/stream_compaction/naive.cu index a22d855..4c0ac0d 100644 --- a/stream_compaction/naive.cu +++ b/stream_compaction/naive.cu @@ -3,8 +3,6 @@ #include "common.h" #include "naive.h" -#define checkCUDAErrorWithLine(msg) checkCUDAError(msg, __LINE__) - namespace StreamCompaction { namespace Naive @@ -15,7 +13,7 @@ namespace StreamCompaction static PerformanceTimer timer; return timer; } - __global__ void kernScan(int n, int layer, int *odata, const int *idata) + __global__ void kernScanNaive(int n, int layer, int *odata, const int *idata) { int index = (blockIdx.x * blockDim.x) + threadIdx.x; if (index >= n) @@ -24,7 +22,8 @@ namespace StreamCompaction } int offset = pow(2, layer); int tmp = idata[index]; - odata[index] = index < offset ? tmp : tmp + idata[index - offset]; + odata[index] = tmp + (index >= offset) * idata[index - offset]; + // index < offset ? tmp : tmp + idata[index - offset]; } /** @@ -34,27 +33,25 @@ namespace StreamCompaction { int power = ilog2ceil(n); int size = pow(2, power); + int offset = size - n; dim3 fullBlocksPerGrid((size + blockSize - 1) / blockSize); - int *bufA; // = new int[size]; - int *bufB; // = new int[size]; + int *bufA; + int *bufB; cudaMalloc((void **)&bufA, size * sizeof(int)); checkCUDAErrorWithLine("cudaMalloc bufA failed!"); cudaMalloc((void **)&bufB, size * sizeof(int)); checkCUDAErrorWithLine("cudaMalloc bufB failed!"); - // std::fill(bufA, bufA + size, 0); - // std::fill(bufB, bufB + size, 0); cudaMemset(bufA, 0, size * sizeof(int)); cudaMemset(bufB, 0, size * sizeof(int)); - // std::copy(idata, idata + n, bufA + size - n); - cudaMemcpy(bufA + size - n, idata, n * sizeof(int), cudaMemcpyHostToDevice); + cudaMemcpy(bufA + offset, idata, n * sizeof(int), cudaMemcpyHostToDevice); int *tmp; timer().startGpuTimer(); // TODO for (int layer = 0; layer < power; layer++) { // invoke kernel - kernScan<<>>(size, layer, bufB, bufA); + kernScanNaive<<>>(size, layer, bufB, bufA); cudaDeviceSynchronize(); // swap bufA and bufB tmp = bufA; @@ -63,14 +60,8 @@ namespace StreamCompaction } cudaDeviceSynchronize(); timer().endGpuTimer(); - int *tmpArr = new int[n]; - cudaMemcpy(tmpArr, bufA + size - n, n * sizeof(int), cudaMemcpyDeviceToHost); + cudaMemcpy(odata + 1, bufA + offset, (n - 1) * sizeof(int), cudaMemcpyDeviceToHost); odata[0] = 0; - for (int i = 1; i < n; i++) - { - odata[i] = tmpArr[i - 1]; - } - delete[] tmpArr; cudaFree(bufA); checkCUDAErrorWithLine("cudaFree bufA failed!"); cudaFree(bufB); From e9d7f8cd4fdfa55ed0580763c6e69e22ace28019 Mon Sep 17 00:00:00 2001 From: LaurelinTheGold Date: Tue, 21 Sep 2021 13:58:11 -0400 Subject: [PATCH 4/9] Now i think upsweep works --- stream_compaction/efficient.cu | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stream_compaction/efficient.cu b/stream_compaction/efficient.cu index 4ab8e69..3d68f02 100644 --- a/stream_compaction/efficient.cu +++ b/stream_compaction/efficient.cu @@ -22,7 +22,7 @@ namespace StreamCompaction return; } int shift = pow(2, layer); - int otherVal = (index & ((1 << layer) - 1) == 0 ? 1 : 0) * + int otherVal = ((index & ((1 << (layer + 1)) - 1)) == 0 ? 1 : 0) * data[index - shift]; __syncthreads(); data[index] += otherVal; @@ -51,6 +51,7 @@ namespace StreamCompaction kernScanEfficientUpSweep<<>>(size, layer, buf); cudaDeviceSynchronize(); } + cudaDeviceSynchronize(); timer().endGpuTimer(); cudaMemcpy(odata + 1, buf + offset, (n - 1) * sizeof(int), cudaMemcpyDeviceToHost); odata[0] = 0; From b2296b6a9404d88961a8fc7919f890dd2c5b32f4 Mon Sep 17 00:00:00 2001 From: LaurelinTheGold Date: Tue, 21 Sep 2021 15:35:16 -0400 Subject: [PATCH 5/9] ok upsweep first pass works --- src/main.cpp | 78 +++++++++++++++++++--------------- stream_compaction/efficient.cu | 47 +++++++++++++++++--- 2 files changed, 85 insertions(+), 40 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 896ac2b..5e5d116 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,13 +13,14 @@ #include #include "testing_helpers.hpp" -const int SIZE = 1 << 8; // feel free to change the size of array +const int SIZE = 1 << 8; // feel free to change the size of array const int NPOT = SIZE - 3; // Non-Power-Of-Two int *a = new int[SIZE]; int *b = new int[SIZE]; int *c = new int[SIZE]; -int main(int argc, char* argv[]) { +int main(int argc, char *argv[]) +{ // Scan tests printf("\n"); @@ -27,7 +28,7 @@ int main(int argc, char* argv[]) { printf("** SCAN TESTS **\n"); printf("****************\n"); - genArray(SIZE - 1, a, 50); // Leave a 0 at the end to test that edge case + genArray(SIZE - 1, a, 50); // Leave a 0 at the end to test that edge case a[SIZE - 1] = 0; printArray(SIZE, a, true); @@ -67,40 +68,49 @@ int main(int argc, char* argv[]) { //printArray(SIZE, c, true); printCmpResult(NPOT, b, c); - zeroArray(SIZE, c); - printDesc("work-efficient scan, power-of-two"); - StreamCompaction::Efficient::scan(SIZE, c, a); - printElapsedTime(StreamCompaction::Efficient::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); - //printArray(SIZE, c, true); - printCmpResult(SIZE, b, c); - - zeroArray(SIZE, c); - printDesc("work-efficient scan, non-power-of-two"); - StreamCompaction::Efficient::scan(NPOT, c, a); + // zeroArray(SIZE, c); + // printDesc("work-efficient scan, power-of-two"); + // StreamCompaction::Efficient::scan(SIZE, c, a); + // printElapsedTime(StreamCompaction::Efficient::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); + // //printArray(SIZE, c, true); + // printCmpResult(SIZE, b, c); + + // zeroArray(SIZE, c); + // printDesc("work-efficient scan, non-power-of-two"); + // StreamCompaction::Efficient::scan(NPOT, c, a); + // printElapsedTime(StreamCompaction::Efficient::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); + // //printArray(NPOT, c, true); + // printCmpResult(NPOT, b, c); + + int tmpTest[] = {0, 1, 2, 3, 4, 5, 6, 7}; + int *tmpTestOut = new int[8]; + zeroArray(8, tmpTestOut); + printDesc("Small array slides example scan"); + StreamCompaction::Efficient::scan(8, tmpTestOut, tmpTest); printElapsedTime(StreamCompaction::Efficient::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); //printArray(NPOT, c, true); printCmpResult(NPOT, b, c); - - zeroArray(SIZE, c); - printDesc("thrust scan, power-of-two"); - StreamCompaction::Thrust::scan(SIZE, c, a); - printElapsedTime(StreamCompaction::Thrust::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); - //printArray(SIZE, c, true); - printCmpResult(SIZE, b, c); - - zeroArray(SIZE, c); - printDesc("thrust scan, non-power-of-two"); - StreamCompaction::Thrust::scan(NPOT, c, a); - printElapsedTime(StreamCompaction::Thrust::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); - //printArray(NPOT, c, true); - printCmpResult(NPOT, b, c); - - printf("\n"); - printf("*****************************\n"); - printf("** STREAM COMPACTION TESTS **\n"); - printf("*****************************\n"); - - // Compaction tests + delete[] tmpTestOut; + +printDesc("thrust scan, power-of-two"); +StreamCompaction::Thrust::scan(SIZE, c, a); +printElapsedTime(StreamCompaction::Thrust::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); +//printArray(SIZE, c, true); +printCmpResult(SIZE, b, c); + +zeroArray(SIZE, c); +printDesc("thrust scan, non-power-of-two"); +StreamCompaction::Thrust::scan(NPOT, c, a); +printElapsedTime(StreamCompaction::Thrust::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); +//printArray(NPOT, c, true); +printCmpResult(NPOT, b, c); + +printf("\n"); +printf("*****************************\n"); +printf("** STREAM COMPACTION TESTS **\n"); +printf("*****************************\n"); + +// Compaction tests genArray(SIZE - 1, a, 4); // Leave a 0 at the end to test that edge case a[SIZE - 1] = 0; diff --git a/stream_compaction/efficient.cu b/stream_compaction/efficient.cu index 3d68f02..006a8cb 100644 --- a/stream_compaction/efficient.cu +++ b/stream_compaction/efficient.cu @@ -22,12 +22,34 @@ namespace StreamCompaction return; } int shift = pow(2, layer); - int otherVal = ((index & ((1 << (layer + 1)) - 1)) == 0 ? 1 : 0) * - data[index - shift]; + int validFlag = (((index + 1) & ((1 << (layer + 1)) - 1)) == 0 ? 1 : 0); + // look at the right place, multiply by whether the bottom bits all 1 + int otherVal = validFlag * data[index - shift]; __syncthreads(); data[index] += otherVal; } + __global__ void kernScanEfficientDownSweep(int n, int layer, int *data) + { + int index = (blockIdx.x * blockDim.x) + threadIdx.x; + if (index >= n) + { + return; + } + int shift = pow(2, layer); + int rChildFlag = ((index & ((1 << (layer + 1)) - 1)) == 0 ? 1 : 0); + int lChildFlag = !rChildFlag && + ((index & ((1 << (layer)) - 1)) == 0 ? 1 : 0); + // int lVal = rChildFlag * data[index - shift]; + // int rVal = lChildFlag * data[index + shift]; + int nextVal = + // case is right child, case not child covered + (lChildFlag == 0) * (data[index] + (rChildFlag * data[index - shift])) + + lChildFlag * data[index + shift]; + __syncthreads(); + data[index] = nextVal; + } + /** * Performs prefix-sum (aka scan) on idata, storing the result into odata. */ @@ -42,19 +64,32 @@ namespace StreamCompaction cudaMalloc((void **)&buf, size * sizeof(int)); checkCUDAErrorWithLine("cudaMalloc buf failed!"); cudaMemset(buf, 0, size * sizeof(int)); + checkCUDAErrorWithLine("cudaMemset buf failed!"); cudaMemcpy(buf + offset, idata, n * sizeof(int), cudaMemcpyHostToDevice); + checkCUDAErrorWithLine("cudaMemcpy buf failed!"); timer().startGpuTimer(); // TODO - for (int layer = 0; layer < power; layer++) + // for (int layer = 0; layer < power; layer++) + for (int layer = 0; layer < 1; layer++) { // invoke kernel kernScanEfficientUpSweep<<>>(size, layer, buf); cudaDeviceSynchronize(); + checkCUDAErrorWithLine("cudaDeviceSynchronize buf failed!"); } - cudaDeviceSynchronize(); + // cudaMemset(buf + size - 1, 0, 1 * sizeof(int)); + // checkCUDAErrorWithLine("cudaMemset buf failed!"); + // for (int layer = power - 1; layer >= 0; layer--) + // { + // // invoke kernel + // kernScanEfficientDownSweep<<>>(size, layer, buf); + // cudaDeviceSynchronize(); + // checkCUDAErrorWithLine("cudaDeviceSynchronize buf failed!"); + // } timer().endGpuTimer(); - cudaMemcpy(odata + 1, buf + offset, (n - 1) * sizeof(int), cudaMemcpyDeviceToHost); - odata[0] = 0; + cudaMemcpy(odata, buf + offset, n * sizeof(int), cudaMemcpyDeviceToHost); + checkCUDAErrorWithLine("cudaMemcpy buf failed!"); + // odata[0] = 0; cudaFree(buf); checkCUDAErrorWithLine("cudaFree buf failed!"); } From dcc8fbd3008375302324a632fa16c6a35e2829f6 Mon Sep 17 00:00:00 2001 From: LaurelinTheGold Date: Tue, 21 Sep 2021 17:06:19 -0400 Subject: [PATCH 6/9] progress on efficient compact --- src/main.cpp | 70 +++++++++---------- stream_compaction/common.cu | 39 ++++++++--- stream_compaction/common.h | 2 +- stream_compaction/efficient.cu | 118 +++++++++++++++++++++++++-------- stream_compaction/naive.cu | 7 +- 5 files changed, 159 insertions(+), 77 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 5e5d116..a0ad578 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -68,51 +68,51 @@ int main(int argc, char *argv[]) //printArray(SIZE, c, true); printCmpResult(NPOT, b, c); - // zeroArray(SIZE, c); - // printDesc("work-efficient scan, power-of-two"); - // StreamCompaction::Efficient::scan(SIZE, c, a); - // printElapsedTime(StreamCompaction::Efficient::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); - // //printArray(SIZE, c, true); - // printCmpResult(SIZE, b, c); + zeroArray(SIZE, c); + printDesc("work-efficient scan, power-of-two"); + StreamCompaction::Efficient::scan(SIZE, c, a); + printElapsedTime(StreamCompaction::Efficient::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); + //printArray(SIZE, c, true); + printCmpResult(SIZE, b, c); + + zeroArray(SIZE, c); + printDesc("work-efficient scan, non-power-of-two"); + StreamCompaction::Efficient::scan(NPOT, c, a); + printElapsedTime(StreamCompaction::Efficient::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); + //printArray(NPOT, c, true); + printCmpResult(NPOT, b, c); - // zeroArray(SIZE, c); - // printDesc("work-efficient scan, non-power-of-two"); - // StreamCompaction::Efficient::scan(NPOT, c, a); + // int tmpTest[] = {0, 1, 2, 3, 4, 5, 6, 7}; + // int *tmpTestOut = new int[8]; + // zeroArray(8, tmpTestOut); + // printDesc("Small array slides example scan"); + // StreamCompaction::Efficient::scan(8, tmpTestOut, tmpTest); // printElapsedTime(StreamCompaction::Efficient::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); // //printArray(NPOT, c, true); // printCmpResult(NPOT, b, c); + // delete[] tmpTestOut; - int tmpTest[] = {0, 1, 2, 3, 4, 5, 6, 7}; - int *tmpTestOut = new int[8]; - zeroArray(8, tmpTestOut); - printDesc("Small array slides example scan"); - StreamCompaction::Efficient::scan(8, tmpTestOut, tmpTest); - printElapsedTime(StreamCompaction::Efficient::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); + printDesc("thrust scan, power-of-two"); + StreamCompaction::Thrust::scan(SIZE, c, a); + printElapsedTime(StreamCompaction::Thrust::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); + //printArray(SIZE, c, true); + printCmpResult(SIZE, b, c); + + zeroArray(SIZE, c); + printDesc("thrust scan, non-power-of-two"); + StreamCompaction::Thrust::scan(NPOT, c, a); + printElapsedTime(StreamCompaction::Thrust::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); //printArray(NPOT, c, true); printCmpResult(NPOT, b, c); - delete[] tmpTestOut; - -printDesc("thrust scan, power-of-two"); -StreamCompaction::Thrust::scan(SIZE, c, a); -printElapsedTime(StreamCompaction::Thrust::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); -//printArray(SIZE, c, true); -printCmpResult(SIZE, b, c); -zeroArray(SIZE, c); -printDesc("thrust scan, non-power-of-two"); -StreamCompaction::Thrust::scan(NPOT, c, a); -printElapsedTime(StreamCompaction::Thrust::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); -//printArray(NPOT, c, true); -printCmpResult(NPOT, b, c); - -printf("\n"); -printf("*****************************\n"); -printf("** STREAM COMPACTION TESTS **\n"); -printf("*****************************\n"); + printf("\n"); + printf("*****************************\n"); + printf("** STREAM COMPACTION TESTS **\n"); + printf("*****************************\n"); -// Compaction tests + // Compaction tests - genArray(SIZE - 1, a, 4); // Leave a 0 at the end to test that edge case + genArray(SIZE - 1, a, 4); // Leave a 0 at the end to test that edge case a[SIZE - 1] = 0; printArray(SIZE, a, true); diff --git a/stream_compaction/common.cu b/stream_compaction/common.cu index 2ed6d63..d3e45a3 100644 --- a/stream_compaction/common.cu +++ b/stream_compaction/common.cu @@ -1,29 +1,39 @@ #include "common.h" -void checkCUDAErrorFn(const char *msg, const char *file, int line) { +void checkCUDAErrorFn(const char *msg, const char *file, int line) +{ cudaError_t err = cudaGetLastError(); - if (cudaSuccess == err) { + if (cudaSuccess == err) + { return; } fprintf(stderr, "CUDA error"); - if (file) { + if (file) + { fprintf(stderr, " (%s:%d)", file, line); } fprintf(stderr, ": %s: %s\n", msg, cudaGetErrorString(err)); exit(EXIT_FAILURE); } - -namespace StreamCompaction { - namespace Common { +namespace StreamCompaction +{ + namespace Common + { /** * Maps an array to an array of 0s and 1s for stream compaction. Elements * which map to 0 will be removed, and elements which map to 1 will be kept. */ - __global__ void kernMapToBoolean(int n, int *bools, const int *idata) { - // TODO + __global__ void kernMapToBoolean(int n, int *bools, const int *idata) + { + int index = (blockIdx.x * blockDim.x) + threadIdx.x; + if (index >= n) + { + return; + } + bools[index] = !(idata[index] == 0); } /** @@ -31,8 +41,17 @@ namespace StreamCompaction { * if bools[idx] == 1, it copies idata[idx] to odata[indices[idx]]. */ __global__ void kernScatter(int n, int *odata, - const int *idata, const int *bools, const int *indices) { - // TODO + const int *idata, const int *bools, const int *indices) + { + int index = (blockIdx.x * blockDim.x) + threadIdx.x; + if (index >= n) + { + return; + } + if (bools[index]) + { + odata[indices[index]] = idata[index]; + } } } diff --git a/stream_compaction/common.h b/stream_compaction/common.h index d3e3e7a..530c406 100644 --- a/stream_compaction/common.h +++ b/stream_compaction/common.h @@ -10,7 +10,7 @@ #include #include -#define blockSize 256 +#define blockSize 1024 #define FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) #define checkCUDAError(msg) checkCUDAErrorFn(msg, FILENAME, __LINE__) diff --git a/stream_compaction/efficient.cu b/stream_compaction/efficient.cu index 006a8cb..cb92f0d 100644 --- a/stream_compaction/efficient.cu +++ b/stream_compaction/efficient.cu @@ -14,42 +14,45 @@ namespace StreamCompaction return timer; } - __global__ void kernScanEfficientUpSweep(int n, int layer, int *data) + __global__ void kernScanEfficientUpSweep(int n, int layer, int shift, int *data) { int index = (blockIdx.x * blockDim.x) + threadIdx.x; if (index >= n) { return; } - int shift = pow(2, layer); - int validFlag = (((index + 1) & ((1 << (layer + 1)) - 1)) == 0 ? 1 : 0); + int validFlag = !((index + 1) & ((1 << (layer + 1)) - 1)); // look at the right place, multiply by whether the bottom bits all 1 int otherVal = validFlag * data[index - shift]; __syncthreads(); data[index] += otherVal; } - __global__ void kernScanEfficientDownSweep(int n, int layer, int *data) + __global__ void kernScanEfficientDownSweep(int n, int layer, int max, int shift, int *data) { int index = (blockIdx.x * blockDim.x) + threadIdx.x; if (index >= n) { return; } - int shift = pow(2, layer); - int rChildFlag = ((index & ((1 << (layer + 1)) - 1)) == 0 ? 1 : 0); + // int rChildFlag = (((index + 1) & ((1 << (layer + 1)) - 1)) == 0 ? 1 : 0); + // int lChildFlag = !rChildFlag && + // (((index + 1) & ((1 << (layer)) - 1)) == 0 ? 1 : 0); + int rChildFlag = !((index + 1) & ((1 << (layer + 1)) - 1)); int lChildFlag = !rChildFlag && - ((index & ((1 << (layer)) - 1)) == 0 ? 1 : 0); - // int lVal = rChildFlag * data[index - shift]; - // int rVal = lChildFlag * data[index + shift]; - int nextVal = - // case is right child, case not child covered - (lChildFlag == 0) * (data[index] + (rChildFlag * data[index - shift])) + - lChildFlag * data[index + shift]; + !((index + 1) & ((1 << (layer)) - 1)); + int nextVal = !lChildFlag * (data[index] + (rChildFlag * data[index - shift])) + + lChildFlag * data[index + shift]; + // nextVal *= !((index == n - 1) && (layer == max)); __syncthreads(); data[index] = nextVal; } + __global__ void kernSetLastToZero(int n, int *data) + { + data[n - 1] = 0; + } + /** * Performs prefix-sum (aka scan) on idata, storing the result into odata. */ @@ -69,27 +72,27 @@ namespace StreamCompaction checkCUDAErrorWithLine("cudaMemcpy buf failed!"); timer().startGpuTimer(); // TODO - // for (int layer = 0; layer < power; layer++) - for (int layer = 0; layer < 1; layer++) + for (int layer = 0; layer < power; layer++) + { + // invoke kernel + int shift = pow(2, layer); + kernScanEfficientUpSweep<<>>(size, layer, shift, buf); + cudaDeviceSynchronize(); + // checkCUDAErrorWithLine("cudaDeviceSynchronize buf failed!"); + } + kernSetLastToZero<<<1, 1>>>(size, buf); + cudaDeviceSynchronize(); + for (int layer = power - 1; layer >= 0; layer--) { // invoke kernel - kernScanEfficientUpSweep<<>>(size, layer, buf); + int shift = pow(2, layer); + kernScanEfficientDownSweep<<>>(size, layer, power - 1, shift, buf); cudaDeviceSynchronize(); - checkCUDAErrorWithLine("cudaDeviceSynchronize buf failed!"); + // checkCUDAErrorWithLine("cudaDeviceSynchronize buf failed!"); } - // cudaMemset(buf + size - 1, 0, 1 * sizeof(int)); - // checkCUDAErrorWithLine("cudaMemset buf failed!"); - // for (int layer = power - 1; layer >= 0; layer--) - // { - // // invoke kernel - // kernScanEfficientDownSweep<<>>(size, layer, buf); - // cudaDeviceSynchronize(); - // checkCUDAErrorWithLine("cudaDeviceSynchronize buf failed!"); - // } timer().endGpuTimer(); cudaMemcpy(odata, buf + offset, n * sizeof(int), cudaMemcpyDeviceToHost); checkCUDAErrorWithLine("cudaMemcpy buf failed!"); - // odata[0] = 0; cudaFree(buf); checkCUDAErrorWithLine("cudaFree buf failed!"); } @@ -105,9 +108,70 @@ namespace StreamCompaction */ int compact(int n, int *odata, const int *idata) { + //next power of 2 + int power = ilog2ceil(n); + int size = pow(2, power); + int offset = size - n; + dim3 fullBlocksPerGrid((size + blockSize - 1) / blockSize); + + int *buf; // power of 2 0 padded copy of idata + cudaMalloc((void **)&buf, size * sizeof(int)); + checkCUDAErrorWithLine("cudaMalloc buf failed!"); + cudaMemset(buf, 0, size * sizeof(int)); + checkCUDAErrorWithLine("cudaMemset buf failed!"); + cudaMemcpy(buf + offset, idata, n * sizeof(int), cudaMemcpyHostToDevice); + checkCUDAErrorWithLine("cudaMemcpy buf failed!"); + + int *bools, *indices, *tmpOut; // + cudaMalloc((void **)&bools, size * sizeof(int)); + checkCUDAErrorWithLine("cudaMalloc bools failed!"); + cudaMalloc((void **)&indices, size * sizeof(int)); + checkCUDAErrorWithLine("cudaMalloc indices failed!"); + cudaMalloc((void **)&tmpOut, size * sizeof(int)); + checkCUDAErrorWithLine("cudaMalloc tmpOut failed!"); timer().startGpuTimer(); // TODO + // Map + Common::kernMapToBoolean<<>>(size, bools, buf); + Common::kernMapToBoolean<<>>(size, indices, buf); + cudaDeviceSynchronize(); + checkCUDAErrorWithLine("cudaDeviceSynchronize failed!"); + // Scan + for (int layer = 0; layer < power; layer++) + { + // invoke kernel + int shift = pow(2, layer); + kernScanEfficientUpSweep<<>>(size, layer, shift, indices); + cudaDeviceSynchronize(); + checkCUDAErrorWithLine("cudaDeviceSynchronize failed!"); + } + kernSetLastToZero<<<1, 1>>>(size, indices); + cudaDeviceSynchronize(); + checkCUDAErrorWithLine("cudaDeviceSynchronize failed!"); + for (int layer = power - 1; layer >= 0; layer--) + { + // invoke kernel + int shift = pow(2, layer); + kernScanEfficientDownSweep<<>>(size, layer, power - 1, shift, indices); + cudaDeviceSynchronize(); + checkCUDAErrorWithLine("cudaDeviceSynchronize failed!"); + } + // Scatter + Common::kernScatter<<>>(size, tmpOut, buf, bools, indices); + cudaDeviceSynchronize(); + checkCUDAErrorWithLine("cudaDeviceSynchronize failed!"); timer().endGpuTimer(); + + cudaMemcpy(odata, tmpOut + offset, n * sizeof(int), cudaMemcpyDeviceToHost); + checkCUDAErrorWithLine("cudaMemcpy failed!"); + cudaFree(buf); + checkCUDAErrorWithLine("cudaFree buf failed!"); + cudaFree(bools); + checkCUDAErrorWithLine("cudaFree bools failed!"); + cudaFree(indices); + checkCUDAErrorWithLine("cudaFree indices failed!"); + cudaFree(tmpOut); + checkCUDAErrorWithLine("cudaFree tmpOut failed!"); return -1; } } diff --git a/stream_compaction/naive.cu b/stream_compaction/naive.cu index 4c0ac0d..66d6ba9 100644 --- a/stream_compaction/naive.cu +++ b/stream_compaction/naive.cu @@ -13,17 +13,15 @@ namespace StreamCompaction static PerformanceTimer timer; return timer; } - __global__ void kernScanNaive(int n, int layer, int *odata, const int *idata) + __global__ void kernScanNaive(int n, int layer, int offset, int *odata, const int *idata) { int index = (blockIdx.x * blockDim.x) + threadIdx.x; if (index >= n) { return; } - int offset = pow(2, layer); int tmp = idata[index]; odata[index] = tmp + (index >= offset) * idata[index - offset]; - // index < offset ? tmp : tmp + idata[index - offset]; } /** @@ -51,7 +49,8 @@ namespace StreamCompaction for (int layer = 0; layer < power; layer++) { // invoke kernel - kernScanNaive<<>>(size, layer, bufB, bufA); + int offset = pow(2, layer); + kernScanNaive<<>>(size, layer, offset, bufB, bufA); cudaDeviceSynchronize(); // swap bufA and bufB tmp = bufA; From f69818b90cc5ee5e83149289c2c7798df4a9cab1 Mon Sep 17 00:00:00 2001 From: LaurelinTheGold Date: Tue, 21 Sep 2021 17:18:45 -0400 Subject: [PATCH 7/9] efficient works --- stream_compaction/efficient.cu | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/stream_compaction/efficient.cu b/stream_compaction/efficient.cu index cb92f0d..67c520f 100644 --- a/stream_compaction/efficient.cu +++ b/stream_compaction/efficient.cu @@ -162,7 +162,16 @@ namespace StreamCompaction checkCUDAErrorWithLine("cudaDeviceSynchronize failed!"); timer().endGpuTimer(); - cudaMemcpy(odata, tmpOut + offset, n * sizeof(int), cudaMemcpyDeviceToHost); + cudaMemcpy(odata, tmpOut, n * sizeof(int), cudaMemcpyDeviceToHost); + checkCUDAErrorWithLine("cudaMemcpy failed!"); + int retSize; + cudaMemcpy(&retSize, indices + size - 1, sizeof(int), cudaMemcpyDeviceToHost); + checkCUDAErrorWithLine("cudaMemcpy failed!"); + int tmpLast; + cudaMemcpy(&tmpLast, buf + size - 1, sizeof(int), cudaMemcpyDeviceToHost); + checkCUDAErrorWithLine("cudaMemcpy failed!"); + retSize += (tmpLast != 0); + checkCUDAErrorWithLine("cudaMemcpy failed!"); cudaFree(buf); checkCUDAErrorWithLine("cudaFree buf failed!"); @@ -172,7 +181,7 @@ namespace StreamCompaction checkCUDAErrorWithLine("cudaFree indices failed!"); cudaFree(tmpOut); checkCUDAErrorWithLine("cudaFree tmpOut failed!"); - return -1; + return retSize; } } } From 0c6223836e2df59e126f65f08f0823528207edbc Mon Sep 17 00:00:00 2001 From: LaurelinTheGold Date: Tue, 21 Sep 2021 19:04:31 -0400 Subject: [PATCH 8/9] redid the kernels based on teh slides --- src/main.cpp | 6 ++-- stream_compaction/common.h | 2 +- stream_compaction/efficient.cu | 63 +++++++++------------------------- stream_compaction/naive.cu | 21 ++++++++---- stream_compaction/thrust.cu | 16 ++++++--- 5 files changed, 47 insertions(+), 61 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a0ad578..e3d1430 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,7 +13,7 @@ #include #include "testing_helpers.hpp" -const int SIZE = 1 << 8; // feel free to change the size of array +const int SIZE = 1 << 23; // feel free to change the size of array const int NPOT = SIZE - 3; // Non-Power-Of-Two int *a = new int[SIZE]; int *b = new int[SIZE]; @@ -50,7 +50,7 @@ int main(int argc, char *argv[]) zeroArray(SIZE, c); printDesc("naive scan, power-of-two"); - StreamCompaction::Naive::scan(SIZE, c, a); + // StreamCompaction::Naive::scan(SIZE, c, a); printElapsedTime(StreamCompaction::Naive::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); //printArray(SIZE, c, true); printCmpResult(SIZE, b, c); @@ -63,7 +63,7 @@ int main(int argc, char *argv[]) zeroArray(SIZE, c); printDesc("naive scan, non-power-of-two"); - StreamCompaction::Naive::scan(NPOT, c, a); + // StreamCompaction::Naive::scan(NPOT, c, a); printElapsedTime(StreamCompaction::Naive::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); //printArray(SIZE, c, true); printCmpResult(NPOT, b, c); diff --git a/stream_compaction/common.h b/stream_compaction/common.h index 530c406..2c1ffa6 100644 --- a/stream_compaction/common.h +++ b/stream_compaction/common.h @@ -10,7 +10,7 @@ #include #include -#define blockSize 1024 +#define blockSize 128 #define FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) #define checkCUDAError(msg) checkCUDAErrorFn(msg, FILENAME, __LINE__) diff --git a/stream_compaction/efficient.cu b/stream_compaction/efficient.cu index 67c520f..ffe6a5d 100644 --- a/stream_compaction/efficient.cu +++ b/stream_compaction/efficient.cu @@ -21,11 +21,10 @@ namespace StreamCompaction { return; } - int validFlag = !((index + 1) & ((1 << (layer + 1)) - 1)); - // look at the right place, multiply by whether the bottom bits all 1 - int otherVal = validFlag * data[index - shift]; - __syncthreads(); - data[index] += otherVal; + if (index % (1 << (layer + 1)) == 0) + { + data[index + (1 << (layer + 1)) - 1] += data[index + (1 << layer) - 1]; + } } __global__ void kernScanEfficientDownSweep(int n, int layer, int max, int shift, int *data) @@ -35,17 +34,12 @@ namespace StreamCompaction { return; } - // int rChildFlag = (((index + 1) & ((1 << (layer + 1)) - 1)) == 0 ? 1 : 0); - // int lChildFlag = !rChildFlag && - // (((index + 1) & ((1 << (layer)) - 1)) == 0 ? 1 : 0); - int rChildFlag = !((index + 1) & ((1 << (layer + 1)) - 1)); - int lChildFlag = !rChildFlag && - !((index + 1) & ((1 << (layer)) - 1)); - int nextVal = !lChildFlag * (data[index] + (rChildFlag * data[index - shift])) + - lChildFlag * data[index + shift]; - // nextVal *= !((index == n - 1) && (layer == max)); - __syncthreads(); - data[index] = nextVal; + if (index % (1 << (layer + 1)) == 0) + { + int t = data[index + (1 << layer) - 1]; + data[index + (1 << layer) - 1] = data[index + (1 << (layer + 1)) - 1]; + data[index + (1 << (layer + 1)) - 1] += t; + } } __global__ void kernSetLastToZero(int n, int *data) @@ -60,41 +54,35 @@ namespace StreamCompaction { //next power of 2 int power = ilog2ceil(n); - int size = pow(2, power); + int size = 1 << power; int offset = size - n; dim3 fullBlocksPerGrid((size + blockSize - 1) / blockSize); int *buf; cudaMalloc((void **)&buf, size * sizeof(int)); - checkCUDAErrorWithLine("cudaMalloc buf failed!"); cudaMemset(buf, 0, size * sizeof(int)); - checkCUDAErrorWithLine("cudaMemset buf failed!"); cudaMemcpy(buf + offset, idata, n * sizeof(int), cudaMemcpyHostToDevice); - checkCUDAErrorWithLine("cudaMemcpy buf failed!"); timer().startGpuTimer(); // TODO for (int layer = 0; layer < power; layer++) { // invoke kernel - int shift = pow(2, layer); + int shift = 1 << layer; kernScanEfficientUpSweep<<>>(size, layer, shift, buf); cudaDeviceSynchronize(); - // checkCUDAErrorWithLine("cudaDeviceSynchronize buf failed!"); } kernSetLastToZero<<<1, 1>>>(size, buf); cudaDeviceSynchronize(); for (int layer = power - 1; layer >= 0; layer--) { // invoke kernel - int shift = pow(2, layer); + int shift = 1 << layer; kernScanEfficientDownSweep<<>>(size, layer, power - 1, shift, buf); cudaDeviceSynchronize(); // checkCUDAErrorWithLine("cudaDeviceSynchronize buf failed!"); } timer().endGpuTimer(); cudaMemcpy(odata, buf + offset, n * sizeof(int), cudaMemcpyDeviceToHost); - checkCUDAErrorWithLine("cudaMemcpy buf failed!"); cudaFree(buf); - checkCUDAErrorWithLine("cudaFree buf failed!"); } /** @@ -110,77 +98,58 @@ namespace StreamCompaction { //next power of 2 int power = ilog2ceil(n); - int size = pow(2, power); + int size = 1 << power; int offset = size - n; dim3 fullBlocksPerGrid((size + blockSize - 1) / blockSize); int *buf; // power of 2 0 padded copy of idata cudaMalloc((void **)&buf, size * sizeof(int)); - checkCUDAErrorWithLine("cudaMalloc buf failed!"); cudaMemset(buf, 0, size * sizeof(int)); - checkCUDAErrorWithLine("cudaMemset buf failed!"); cudaMemcpy(buf + offset, idata, n * sizeof(int), cudaMemcpyHostToDevice); - checkCUDAErrorWithLine("cudaMemcpy buf failed!"); int *bools, *indices, *tmpOut; // cudaMalloc((void **)&bools, size * sizeof(int)); - checkCUDAErrorWithLine("cudaMalloc bools failed!"); cudaMalloc((void **)&indices, size * sizeof(int)); - checkCUDAErrorWithLine("cudaMalloc indices failed!"); cudaMalloc((void **)&tmpOut, size * sizeof(int)); - checkCUDAErrorWithLine("cudaMalloc tmpOut failed!"); timer().startGpuTimer(); // TODO // Map Common::kernMapToBoolean<<>>(size, bools, buf); Common::kernMapToBoolean<<>>(size, indices, buf); cudaDeviceSynchronize(); - checkCUDAErrorWithLine("cudaDeviceSynchronize failed!"); // Scan for (int layer = 0; layer < power; layer++) { // invoke kernel - int shift = pow(2, layer); + int shift = 1 << layer; kernScanEfficientUpSweep<<>>(size, layer, shift, indices); cudaDeviceSynchronize(); - checkCUDAErrorWithLine("cudaDeviceSynchronize failed!"); } kernSetLastToZero<<<1, 1>>>(size, indices); cudaDeviceSynchronize(); - checkCUDAErrorWithLine("cudaDeviceSynchronize failed!"); for (int layer = power - 1; layer >= 0; layer--) { // invoke kernel - int shift = pow(2, layer); + int shift = 1 << layer; kernScanEfficientDownSweep<<>>(size, layer, power - 1, shift, indices); cudaDeviceSynchronize(); - checkCUDAErrorWithLine("cudaDeviceSynchronize failed!"); } // Scatter Common::kernScatter<<>>(size, tmpOut, buf, bools, indices); cudaDeviceSynchronize(); - checkCUDAErrorWithLine("cudaDeviceSynchronize failed!"); timer().endGpuTimer(); cudaMemcpy(odata, tmpOut, n * sizeof(int), cudaMemcpyDeviceToHost); - checkCUDAErrorWithLine("cudaMemcpy failed!"); int retSize; cudaMemcpy(&retSize, indices + size - 1, sizeof(int), cudaMemcpyDeviceToHost); - checkCUDAErrorWithLine("cudaMemcpy failed!"); int tmpLast; cudaMemcpy(&tmpLast, buf + size - 1, sizeof(int), cudaMemcpyDeviceToHost); - checkCUDAErrorWithLine("cudaMemcpy failed!"); retSize += (tmpLast != 0); - checkCUDAErrorWithLine("cudaMemcpy failed!"); cudaFree(buf); - checkCUDAErrorWithLine("cudaFree buf failed!"); cudaFree(bools); - checkCUDAErrorWithLine("cudaFree bools failed!"); cudaFree(indices); - checkCUDAErrorWithLine("cudaFree indices failed!"); cudaFree(tmpOut); - checkCUDAErrorWithLine("cudaFree tmpOut failed!"); return retSize; } } diff --git a/stream_compaction/naive.cu b/stream_compaction/naive.cu index 66d6ba9..ce8d6b1 100644 --- a/stream_compaction/naive.cu +++ b/stream_compaction/naive.cu @@ -21,7 +21,7 @@ namespace StreamCompaction return; } int tmp = idata[index]; - odata[index] = tmp + (index >= offset) * idata[index - offset]; + odata[index] = tmp + (index >= offset) ? idata[index - offset] : 0; } /** @@ -30,7 +30,7 @@ namespace StreamCompaction void scan(int n, int *odata, const int *idata) { int power = ilog2ceil(n); - int size = pow(2, power); + int size = 1 << power; int offset = size - n; dim3 fullBlocksPerGrid((size + blockSize - 1) / blockSize); int *bufA; @@ -43,28 +43,37 @@ namespace StreamCompaction cudaMemset(bufA, 0, size * sizeof(int)); cudaMemset(bufB, 0, size * sizeof(int)); cudaMemcpy(bufA + offset, idata, n * sizeof(int), cudaMemcpyHostToDevice); + checkCUDAErrorWithLine("cudaMemcpy failed!"); int *tmp; timer().startGpuTimer(); // TODO for (int layer = 0; layer < power; layer++) { // invoke kernel - int offset = pow(2, layer); + int offset = 1 << layer; + checkCUDAErrorWithLine("loop start failed!"); kernScanNaive<<>>(size, layer, offset, bufB, bufA); + checkCUDAErrorWithLine("kernscan failed!"); cudaDeviceSynchronize(); + checkCUDAErrorWithLine("cudaDeviceSync failed!"); // swap bufA and bufB tmp = bufA; bufA = bufB; bufB = tmp; } - cudaDeviceSynchronize(); + checkCUDAErrorWithLine("before memcpy failed!"); + + // cudaDeviceSynchronize(); timer().endGpuTimer(); cudaMemcpy(odata + 1, bufA + offset, (n - 1) * sizeof(int), cudaMemcpyDeviceToHost); + checkCUDAErrorWithLine("cudaMemcpy failed!"); + odata[0] = 0; - cudaFree(bufA); - checkCUDAErrorWithLine("cudaFree bufA failed!"); + // cudaDeviceSynchronize(); cudaFree(bufB); checkCUDAErrorWithLine("cudaFree bufB failed!"); + cudaFree(bufA); + checkCUDAErrorWithLine("cudaFree bufA failed!"); } } } diff --git a/stream_compaction/thrust.cu b/stream_compaction/thrust.cu index 1def45e..afe7719 100644 --- a/stream_compaction/thrust.cu +++ b/stream_compaction/thrust.cu @@ -6,10 +6,12 @@ #include "common.h" #include "thrust.h" -namespace StreamCompaction { - namespace Thrust { +namespace StreamCompaction +{ + namespace Thrust + { using StreamCompaction::Common::PerformanceTimer; - PerformanceTimer& timer() + PerformanceTimer &timer() { static PerformanceTimer timer; return timer; @@ -17,12 +19,18 @@ namespace StreamCompaction { /** * Performs prefix-sum (aka scan) on idata, storing the result into odata. */ - void scan(int n, int *odata, const int *idata) { + void scan(int n, int *odata, const int *idata) + { + thrust::host_vector hv_idata(idata, idata + n); + thrust::device_vector dv_idata(hv_idata); + thrust::device_vector dv_odata(n); timer().startGpuTimer(); // TODO use `thrust::exclusive_scan` // example: for device_vectors dv_in and dv_out: // thrust::exclusive_scan(dv_in.begin(), dv_in.end(), dv_out.begin()); + thrust::exclusive_scan(dv_idata.begin(), dv_idata.end(), dv_odata.begin()); timer().endGpuTimer(); + thrust::copy(dv_odata.begin(), dv_odata.end(), odata); } } } From efa20032c7c64376c84015167348bd2b23bda1ce Mon Sep 17 00:00:00 2001 From: LaurelinTheGold Date: Tue, 21 Sep 2021 22:36:42 -0400 Subject: [PATCH 9/9] done --- README.md | 132 +++++++++++++++++++++++++++++++++++-- img/profile_timeline.png | Bin 0 -> 49382 bytes img/scan_time.png | Bin 0 -> 65285 bytes img/stream_time.png | Bin 0 -> 51269 bytes img/time_blocksize.png | Bin 0 -> 13533 bytes src/main.cpp | 6 +- stream_compaction/common.h | 2 +- stream_compaction/naive.cu | 2 +- 8 files changed, 131 insertions(+), 11 deletions(-) create mode 100644 img/profile_timeline.png create mode 100644 img/scan_time.png create mode 100644 img/stream_time.png create mode 100644 img/time_blocksize.png diff --git a/README.md b/README.md index 0e38ddb..1f5e25e 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,132 @@ CUDA Stream Compaction **University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 2** -* (TODO) YOUR NAME HERE - * (TODO) [LinkedIn](), [personal website](), [twitter](), etc. -* Tested on: (TODO) Windows 22, i7-2222 @ 2.22GHz 22GB, GTX 222 222MB (Moore 2222 Lab) +* Richard Chen + * [LinkedIn](https://www.linkedin.com/in/richardrlchen/) +* Tested on: Windows 11, i7-10875H @ 2.3GHz 16GB, RTX 2060 MAXQ 6GB (PC) + +## Overview +The purpose of this project was to explore parallel algorithms, something a GPU +excels at. To that end, we used the GPU to perform stream compaction via scan. +Stream compaction filters out elements from a list, in this case discarding the 0 +elements from the input. Scan is a fold but all the intermediate steps are also +available. + +## Features +* CPU implementation of scan +* CPU implementation of stream compaction +* Naive parallel version of scan for GPU implemented in CUDA +* Work efficient parallel version of scan for GPU implemented in CUDA +* Stream Compaction that leverages the GPU scan + +## Example Output +Tested on 256 element array +``` +**************** +** SCAN TESTS ** +**************** + [ 28 7 23 2 29 27 22 19 2 38 26 47 45 ... 43 0 ] +==== cpu scan, power-of-two ==== + elapsed time: 0.0005ms (std::chrono Measured) + [ 0 28 35 58 60 89 116 138 157 159 197 223 270 ... 6050 6093 ] +==== cpu scan, non-power-of-two ==== + elapsed time: 0.0003ms (std::chrono Measured) + [ 0 28 35 58 60 89 116 138 157 159 197 223 270 ... 6016 6031 ] + passed +==== naive scan, power-of-two ==== + elapsed time: 0.243616ms (CUDA Measured) + a[1] = 28, b[1] = 0 + FAIL VALUE +==== naive scan, non-power-of-two ==== + elapsed time: 0.17504ms (CUDA Measured) + a[1] = 28, b[1] = 0 + FAIL VALUE +==== work-efficient scan, power-of-two ==== + elapsed time: 0.325728ms (CUDA Measured) + passed +==== work-efficient scan, non-power-of-two ==== + elapsed time: 0.335584ms (CUDA Measured) + passed +==== thrust scan, power-of-two ==== + elapsed time: 0.1088ms (CUDA Measured) + passed +==== thrust scan, non-power-of-two ==== + elapsed time: 0.048928ms (CUDA Measured) + passed + +***************************** +** STREAM COMPACTION TESTS ** +***************************** + [ 0 3 1 3 1 1 0 2 2 0 0 1 2 ... 3 0 ] +==== cpu compact without scan, power-of-two ==== + elapsed time: 0.0013ms (std::chrono Measured) + [ 3 1 3 1 1 2 2 1 2 2 2 1 2 ... 3 3 ] + passed +==== cpu compact without scan, non-power-of-two ==== + elapsed time: 0.0012ms (std::chrono Measured) + [ 3 1 3 1 1 2 2 1 2 2 2 1 2 ... 2 2 ] + passed +==== cpu compact with scan ==== + elapsed time: 0.0015ms (std::chrono Measured) + [ 3 1 3 1 1 2 2 1 2 2 2 1 2 ... 3 3 ] + passed +==== work-efficient compact, power-of-two ==== + elapsed time: 0.36784ms (CUDA Measured) + passed +==== work-efficient compact, non-power-of-two ==== + elapsed time: 0.3792ms (CUDA Measured) + passed +Press any key to continue . . . +``` + +## Performance Analysis +Optimizing Block Size +
+ + +There does not seem to be a significant difference when tested on size 2^16. + +Performance as a function of array length +
+ + +Notice that the time axis is log scaled. The crossover between the naive and +efficient implementations happens around length 2^19. + +Stream Compaction as a function of array length +
+ + +Notice that the time axis is log scaled. Even with arrays of up to length +2^28, the single threaded CPU is still faster for stream compactification. +This goes to show how parallelism and concurrency should be used situationally +as in many scenarios, the drawbacks might outweigh the benefits. + +### Nsight +Profiling the execution on arrays of length 2^16 +
+ +In the CUDA HW row, green represents host->device and +red represents device->host. Thus we can see that these pairs neatly bracket +the naive implementation, the work-efficient implementation, and using +the thrust library. + +Up to 936ms is the naive GPU version. It looks about half as long as the +work efficient implementation. The work efficient implementation iterates through +the layers of the "tree" twice, once on the upsweep and once on the downsweep. +Until the arrays are large enough, the larger number of computations performed +will not overcome the overhead incurred from taking twice the number of steps. +When tested on length 2^20 arrays, the work efficient implementation was faster. + +The thrust implementation is significantly faster and also has far fewer kernel +calls. This seems reasonable as there probably is overhead that is incurred when +spawning multiple kernels so being able to fit the operation into fewer kernel +calls would drastically cut down on this. Additionally, thrust probably has +shared memory optimizations, memory access optimizations, and more efficient +computation. + +For all 3, the kernel executions themselves have lots of empty time in between +computations which suggests there is some form of IO bottleneck. -### (TODO: Your README) -Include analysis, etc. (Remember, this is public, so don't put -anything here that you don't want to share with the world.) diff --git a/img/profile_timeline.png b/img/profile_timeline.png new file mode 100644 index 0000000000000000000000000000000000000000..7d85b71adc5db03b4f482031242a20d6517d6ba3 GIT binary patch literal 49382 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�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 VxW?2Sn7;Rb)@?oYl3O<6{{yBT+-U#+ literal 0 HcmV?d00001 diff --git a/img/scan_time.png b/img/scan_time.png new file mode 100644 index 0000000000000000000000000000000000000000..53641b9804e8a3102b0d0b22f092addbf8a4d140 GIT binary patch literal 65285 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

NX}W)y~ZB#hH_x-}Z5^9Jmt-|-|6zBUNv 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 WT<@1uT0OFtG*p!}l#sU{2mBv%`e@7m literal 0 HcmV?d00001 diff --git a/img/time_blocksize.png b/img/time_blocksize.png new file mode 100644 index 0000000000000000000000000000000000000000..43639465493dd263c1717e06897fb190077f3ce0 GIT binary patch literal 13533 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 literal 0 HcmV?d00001 diff --git a/src/main.cpp b/src/main.cpp index e3d1430..5562fb8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,7 +13,7 @@ #include #include "testing_helpers.hpp" -const int SIZE = 1 << 23; // feel free to change the size of array +const int SIZE = 1 << 12; // feel free to change the size of array const int NPOT = SIZE - 3; // Non-Power-Of-Two int *a = new int[SIZE]; int *b = new int[SIZE]; @@ -50,7 +50,7 @@ int main(int argc, char *argv[]) zeroArray(SIZE, c); printDesc("naive scan, power-of-two"); - // StreamCompaction::Naive::scan(SIZE, c, a); + StreamCompaction::Naive::scan(SIZE, c, a); printElapsedTime(StreamCompaction::Naive::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); //printArray(SIZE, c, true); printCmpResult(SIZE, b, c); @@ -63,7 +63,7 @@ int main(int argc, char *argv[]) zeroArray(SIZE, c); printDesc("naive scan, non-power-of-two"); - // StreamCompaction::Naive::scan(NPOT, c, a); + StreamCompaction::Naive::scan(NPOT, c, a); printElapsedTime(StreamCompaction::Naive::timer().getGpuElapsedTimeForPreviousOperation(), "(CUDA Measured)"); //printArray(SIZE, c, true); printCmpResult(NPOT, b, c); diff --git a/stream_compaction/common.h b/stream_compaction/common.h index 2c1ffa6..530c406 100644 --- a/stream_compaction/common.h +++ b/stream_compaction/common.h @@ -10,7 +10,7 @@ #include #include -#define blockSize 128 +#define blockSize 1024 #define FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) #define checkCUDAError(msg) checkCUDAErrorFn(msg, FILENAME, __LINE__) diff --git a/stream_compaction/naive.cu b/stream_compaction/naive.cu index ce8d6b1..b2a8ba5 100644 --- a/stream_compaction/naive.cu +++ b/stream_compaction/naive.cu @@ -21,7 +21,7 @@ namespace StreamCompaction return; } int tmp = idata[index]; - odata[index] = tmp + (index >= offset) ? idata[index - offset] : 0; + odata[index] = tmp + ((index >= offset) ? idata[index - offset] : 0); } /**