Revision: 1508
http://rigsofrods.svn.sourceforge.net/rigsofrods/?rev=1508&view=rev
Author: rorthomas
Date: 2010-08-08 19:45:12 +0000 (Sun, 08 Aug 2010)
Log Message:
-----------
added OpenCL bandwidth check
Modified Paths:
--------------
trunk/source/configurator/configurator.cpp
Added Paths:
-----------
trunk/source/configurator/ocl_bwtest.h
Modified: trunk/source/configurator/configurator.cpp
===================================================================
--- trunk/source/configurator/configurator.cpp 2010-08-08 18:48:11 UTC (rev
1507)
+++ trunk/source/configurator/configurator.cpp 2010-08-08 19:45:12 UTC (rev
1508)
@@ -247,6 +247,7 @@
void OnButClearCache(wxCommandEvent& event);
void OnButUpdateRoR(wxCommandEvent& event);
void OnButCheckOpenCL(wxCommandEvent& event);
+ void OnButCheckOpenCLBW(wxCommandEvent& event);
void updateRoR();
void OnSimpleSliderScroll(wxScrollEvent& event);
void OnSimpleSlider2Scroll(wxScrollEvent& event);
@@ -1062,6 +1063,7 @@
FFSLIDER,
get_user_token,
check_opencl,
+ check_opencl_bw,
};
// ----------------------------------------------------------------------------
@@ -1084,6 +1086,7 @@
EVT_BUTTON(regen_cache, MyDialog::OnButRegenCache)
EVT_BUTTON(update_ror, MyDialog::OnButUpdateRoR)
EVT_BUTTON(check_opencl, MyDialog::OnButCheckOpenCL)
+ EVT_BUTTON(check_opencl_bw, MyDialog::OnButCheckOpenCLBW)
EVT_HTML_LINK_CLICKED(main_html, MyDialog::OnLinkClicked)
EVT_HTML_LINK_CLICKED(update_html, MyDialog::OnLinkClickedUpdate)
//EVT_SCROLL(MyDialog::OnSightRangeScroll)
@@ -2137,11 +2140,14 @@
gputext = new wxTextCtrl(GPUPanel, wxID_ANY, _("press the button below
to check if OpenCL is working for you"), wxDefaultPosition, wxDefaultSize,
wxTE_READONLY|wxTE_MULTILINE);
sizer_gpu2->Add(gputext, 1, wxGROW);
- sizer_gpu->Add(sizer_gpu2, 0, wxGROW);
+ sizer_gpu->Add(sizer_gpu2, 1, wxGROW);
wxButton *btng = new wxButton(GPUPanel, check_opencl, _("Check for
OpenCL Support"));
sizer_gpu->Add(btng, 0, wxGROW);
+ wxButton *btnw = new wxButton(GPUPanel, check_opencl_bw, _("Check
OpenCL Bandwidth"));
+ sizer_gpu->Add(btnw, 0, wxGROW);
+
GPUPanel->SetSizer(sizer_gpu);
#endif // USE_OPENCL
@@ -3392,8 +3398,20 @@
#ifdef USE_OPENCL
#include <oclUtils.h>
+
+#include "ocl_bwtest.h"
#endif // USE_OPENCL
+void MyDialog::OnButCheckOpenCLBW(wxCommandEvent& event)
+{
+#ifdef USE_OPENCL
+ gputext->SetValue("");
+ ostream tstream(gputext);
+ OpenCLTestBandwidth bw_test(tstream);
+
+#endif // USE_OPENCL
+}
+
void MyDialog::OnButCheckOpenCL(wxCommandEvent& event)
{
#ifdef USE_OPENCL
Added: trunk/source/configurator/ocl_bwtest.h
===================================================================
--- trunk/source/configurator/ocl_bwtest.h (rev 0)
+++ trunk/source/configurator/ocl_bwtest.h 2010-08-08 19:45:12 UTC (rev
1508)
@@ -0,0 +1,690 @@
+/*
+ * Copyright 1993-2010 NVIDIA Corporation. All rights reserved.
+ *
+ * NVIDIA Corporation and its licensors retain all intellectual property and
+ * proprietary rights in and to this software and related documentation.
+ * Any use, reproduction, disclosure, or distribution of this software
+ * and related documentation without an express license agreement from
+ * NVIDIA Corporation is strictly prohibited.
+ *
+ * Please refer to the applicable NVIDIA end user license agreement (EULA)
+ * associated with this source code for terms and conditions that govern
+ * your use of this NVIDIA software.
+ *
+ */
+
+// *********************************************************************
+//
+// *********************************************************************
+
+// standard utilities and systems includes
+#include <oclUtils.h>
+
+// defines, project
+#define MEMCOPY_ITERATIONS 100
+#define DEFAULT_SIZE ( 32 * ( 1 << 20 ) ) //32 M
+#define DEFAULT_INCREMENT (1 << 22) //4 M
+#define CACHE_CLEAR_SIZE (1 << 24) //16 M
+
+//shmoo mode defines
+#define SHMOO_MEMSIZE_MAX (1 << 26) //64 M
+#define SHMOO_MEMSIZE_START (1 << 10) //1 KB
+#define SHMOO_INCREMENT_1KB (1 << 10) //1 KB
+#define SHMOO_INCREMENT_2KB (1 << 11) //2 KB
+#define SHMOO_INCREMENT_10KB (10 * (1 << 10)) //10KB
+#define SHMOO_INCREMENT_100KB (100 * (1 << 10)) //100 KB
+#define SHMOO_INCREMENT_1MB (1 << 20) //1 MB
+#define SHMOO_INCREMENT_2MB (1 << 21) //2 MB
+#define SHMOO_INCREMENT_4MB (1 << 22) //4 MB
+#define SHMOO_LIMIT_20KB (20 * (1 << 10)) //20 KB
+#define SHMOO_LIMIT_50KB (50 * (1 << 10)) //50 KB
+#define SHMOO_LIMIT_100KB (100 * (1 << 10)) //100 KB
+#define SHMOO_LIMIT_1MB (1 << 20) //1 MB
+#define SHMOO_LIMIT_16MB (1 << 24) //16 MB
+#define SHMOO_LIMIT_32MB (1 << 25) //32 MB
+
+//enums, project
+enum testMode { QUICK_MODE, RANGE_MODE, SHMOO_MODE };
+enum memcpyKind { DEVICE_TO_HOST, HOST_TO_DEVICE, DEVICE_TO_DEVICE };
+enum memoryMode { PAGEABLE, PINNED };
+enum accessMode { MAPPED, DIRECT };
+
+#include <iostream>
+using namespace std;
+
+class OpenCLTestBandwidth
+{
+public:
+ OpenCLTestBandwidth(std::ostream &stream);
+ ~OpenCLTestBandwidth();
+
+protected:
+ std::ostream &stream;
+
+ // CL objects
+ cl_context cxGPUContext;
+ cl_command_queue cqCommandQueue;
+ cl_device_id *devices;
+
+
////////////////////////////////////////////////////////////////////////////////
+ // declaration, forward
+ int runTest(memoryMode memMode = PAGEABLE, accessMode accMode = DIRECT,
testMode mode = QUICK_MODE);
+ void createQueue(unsigned int device);
+ void testBandwidth( unsigned int start, unsigned int end, unsigned int
increment,
+ testMode mode, memcpyKind kind,
accessMode accMode, memoryMode memMode, int startDevice, int endDevice);
+ void testBandwidthQuick(unsigned int size, memcpyKind kind, accessMode
accMode, memoryMode memMode, int startDevice, int endDevice);
+ void testBandwidthRange(unsigned int start, unsigned int end, unsigned
int increment,
+ memcpyKind kind,
accessMode accMode, memoryMode memMode, int startDevice, int endDevice);
+ void testBandwidthShmoo(memcpyKind kind, accessMode accMode,
memoryMode memMode, int startDevice, int endDevice);
+ double testDeviceToHostTransfer(unsigned int memSize, accessMode
accMode, memoryMode memMode);
+ double testHostToDeviceTransfer(unsigned int memSize, accessMode
accMode, memoryMode memMode);
+ double testDeviceToDeviceTransfer(unsigned int memSize);
+ void printResultsReadable(unsigned int *memSizes, double* bandwidths,
unsigned int count, memcpyKind kind, accessMode accMode, memoryMode memMode,
int iNumDevs);
+};
+
+// class implementation
+
+OpenCLTestBandwidth::OpenCLTestBandwidth(std::ostream &_stream) :
stream(_stream), cqCommandQueue(0), devices(0)
+{
+ stream << "Starting, this can take a while ..." << endl;
+ stream.flush();
+
+ // run the main test
+ int iRetVal = runTest();
+
+ stream << endl;
+
+ if(iRetVal == 0)
+ stream << "=== PASSED ===" << endl;
+ else
+ stream << "=== FAILED ===" << endl;
+}
+
+OpenCLTestBandwidth::~OpenCLTestBandwidth()
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//Parse args, run the appropriate tests
+///////////////////////////////////////////////////////////////////////////////
+int OpenCLTestBandwidth::runTest(memoryMode memMode, accessMode accMode,
testMode mode)
+{
+ int start = DEFAULT_SIZE;
+ int end = DEFAULT_SIZE;
+ int startDevice = 0;
+ int endDevice = 0;
+ int increment = DEFAULT_INCREMENT;
+ bool htod = false;
+ bool dtoh = false;
+ bool dtod = false;
+
+ // Get OpenCL platform ID for NVIDIA if available, otherwise default
+ cl_platform_id clSelectedPlatformID = NULL;
+ cl_int ciErrNum = oclGetPlatformID (&clSelectedPlatformID);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+
+ // Find out how many devices there are
+ cl_uint ciDeviceCount;
+ ciErrNum = clGetDeviceIDs (clSelectedPlatformID, CL_DEVICE_TYPE_GPU, 0,
NULL, &ciDeviceCount);
+ if (ciErrNum != CL_SUCCESS)
+ {
+ stream << "Error in clGetDeviceIDs call: " << ciErrNum << endl;
+ return ciErrNum;
+ }
+ else if (ciDeviceCount == 0)
+ {
+ stream << "There are no devices supporting OpenCL return code" <<
ciErrNum << endl;
+ return ciErrNum;
+ }
+
+ // use all devices
+ startDevice = 0;
+ endDevice = (int)(ciDeviceCount-1);
+
+
+ // Get and log the device info
+ devices = (cl_device_id*) malloc(sizeof(cl_device_id) * ciDeviceCount);
+ ciErrNum = clGetDeviceIDs (clSelectedPlatformID, CL_DEVICE_TYPE_GPU,
ciDeviceCount, devices, &ciDeviceCount);
+ for(int currentDevice = startDevice; currentDevice <= endDevice;
currentDevice++)
+ {
+ char device_string[1024];
+ clGetDeviceInfo(devices[currentDevice], CL_DEVICE_NAME,
sizeof(device_string), &device_string, NULL);
+ stream << "Running on " << device_string << endl << endl;
+ }
+
+
+ //default: All tests
+ htod = true;
+ dtoh = true;
+ dtod = true;
+
+
+ // Create the OpenCL context
+ cxGPUContext = clCreateContext(0, ciDeviceCount, devices, NULL, NULL,
NULL);
+ if (cxGPUContext == (cl_context)0)
+ {
+ stream << "Failed to create OpenCL context!" << endl;
+ return -11000;
+ }
+
+ // Run tests
+ if(htod)
+ {
+ testBandwidth((unsigned int)start, (unsigned int)end, (unsigned
int)increment,
+ mode, HOST_TO_DEVICE, accMode, memMode, startDevice,
endDevice);
+ }
+
+ stream << endl;
+
+ if(dtoh)
+ {
+ testBandwidth((unsigned int)start, (unsigned int)end, (unsigned
int)increment,
+ mode, DEVICE_TO_HOST, accMode, memMode, startDevice,
endDevice);
+ }
+
+ stream << endl;
+
+ if(dtod)
+ {
+ testBandwidth((unsigned int)start, (unsigned int)end, (unsigned
int)increment,
+ mode, DEVICE_TO_DEVICE, accMode, memMode, startDevice,
endDevice);
+ }
+
+ stream << endl;
+
+ // Clean up
+ if(cqCommandQueue)clReleaseCommandQueue(cqCommandQueue);
+ if(cxGPUContext)clReleaseContext(cxGPUContext);
+ if(devices)free(devices);
+
+ return 0;
+}
+///////////////////////////////////////////////////////////////////////////////
+// Create command queue for the selected device
+///////////////////////////////////////////////////////////////////////////////
+void OpenCLTestBandwidth::createQueue(unsigned int device)
+{
+ // Release if there previous is already one
+ if(cqCommandQueue)
+ {
+ clReleaseCommandQueue(cqCommandQueue);
+ }
+
+ cqCommandQueue = clCreateCommandQueue(cxGPUContext, devices[device],
CL_QUEUE_PROFILING_ENABLE, NULL);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Run a bandwidth test
+///////////////////////////////////////////////////////////////////////////////
+void OpenCLTestBandwidth::testBandwidth(unsigned int start, unsigned int end,
unsigned int increment,
+ testMode mode, memcpyKind kind, accessMode accMode,
+ memoryMode memMode, int startDevice, int endDevice)
+{
+ switch(mode)
+ {
+ case QUICK_MODE:
+ testBandwidthQuick( DEFAULT_SIZE, kind, accMode, memMode, startDevice,
endDevice);
+ break;
+ case RANGE_MODE:
+ testBandwidthRange(start, end, increment, kind, accMode, memMode,
startDevice, endDevice);
+ break;
+ case SHMOO_MODE:
+ testBandwidthShmoo(kind, accMode, memMode, startDevice, endDevice);
+ break;
+ default:
+ break;
+ }
+
+}
+//////////////////////////////////////////////////////////////////////
+// Run a quick mode bandwidth test
+//////////////////////////////////////////////////////////////////////
+void OpenCLTestBandwidth::testBandwidthQuick(unsigned int size, memcpyKind
kind, accessMode accMode,
+ memoryMode memMode, int startDevice, int endDevice)
+{
+ testBandwidthRange(size, size, DEFAULT_INCREMENT, kind, accMode, memMode,
startDevice, endDevice);
+}
+
+///////////////////////////////////////////////////////////////////////
+// Run a range mode bandwidth test
+//////////////////////////////////////////////////////////////////////
+void OpenCLTestBandwidth::testBandwidthRange(unsigned int start, unsigned int
end, unsigned int increment,
+ memcpyKind kind, accessMode accMode, memoryMode memMode,
int startDevice, int endDevice)
+{
+ //count the number of copies we're going to run
+ unsigned int count = 1 + ((end - start) / increment);
+
+ unsigned int * memSizes = (unsigned int *)malloc(count * sizeof( unsigned
int ));
+ double* bandwidths = (double*)malloc(count * sizeof(double));
+
+ // Before calculating the cumulative bandwidth, initialize bandwidths
array to NULL
+ for (unsigned int i = 0; i < count; i++)
+ bandwidths[i] = 0.0;
+
+ // Use the device asked by the user
+ for (int currentDevice = startDevice; currentDevice <= endDevice;
currentDevice++)
+ {
+ // Allocate command queue for the device (dealloc first if already
allocated)
+ createQueue(currentDevice);
+
+ //run each of the copies
+ for(unsigned int i = 0; i < count; i++)
+ {
+ memSizes[i] = start + i * increment;
+ switch(kind)
+ {
+ case DEVICE_TO_HOST: bandwidths[i] +=
testDeviceToHostTransfer(memSizes[i], accMode, memMode);
+ break;
+ case HOST_TO_DEVICE: bandwidths[i] +=
testHostToDeviceTransfer(memSizes[i], accMode, memMode);
+ break;
+ case DEVICE_TO_DEVICE: bandwidths[i] +=
testDeviceToDeviceTransfer(memSizes[i]);
+ break;
+ }
+ }
+ } // Complete the bandwidth computation on all the devices
+
+ //print results
+ printResultsReadable(memSizes, bandwidths, count, kind, accMode,
memMode, (1 + endDevice - startDevice));
+
+ //clean up
+ free(memSizes);
+ free(bandwidths);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Intense shmoo mode - covers a large range of values with varying increments
+//////////////////////////////////////////////////////////////////////////////
+void OpenCLTestBandwidth::testBandwidthShmoo(memcpyKind kind, accessMode
accMode,
+ memoryMode memMode, int startDevice, int endDevice)
+{
+ //count the number of copies to make
+ unsigned int count = 1 + (SHMOO_LIMIT_20KB / SHMOO_INCREMENT_1KB)
+ + ((SHMOO_LIMIT_50KB - SHMOO_LIMIT_20KB) / SHMOO_INCREMENT_2KB)
+ + ((SHMOO_LIMIT_100KB - SHMOO_LIMIT_50KB) / SHMOO_INCREMENT_10KB)
+ + ((SHMOO_LIMIT_1MB - SHMOO_LIMIT_100KB) / SHMOO_INCREMENT_100KB)
+ + ((SHMOO_LIMIT_16MB - SHMOO_LIMIT_1MB) / SHMOO_INCREMENT_1MB)
+ + ((SHMOO_LIMIT_32MB - SHMOO_LIMIT_16MB) / SHMOO_INCREMENT_2MB)
+ + ((SHMOO_MEMSIZE_MAX - SHMOO_LIMIT_32MB) / SHMOO_INCREMENT_4MB);
+
+ unsigned int *memSizes = (unsigned int *)malloc(count * sizeof(unsigned
int));
+ double* bandwidths = (double*)malloc(count * sizeof(double));
+
+ // Before calculating the cumulative bandwidth, initialize bandwidths
array to NULL
+ for (unsigned int i = 0; i < count; i++)
+ bandwidths[i] = 0.0;
+
+ // Use the device asked by the user
+ for (int currentDevice = startDevice; currentDevice <= endDevice;
currentDevice++)
+ {
+ // Allocate command queue for the device (dealloc first if already
allocated)
+ createQueue(currentDevice);
+
+ //Run the shmoo
+ int iteration = 0;
+ unsigned int memSize = 0;
+ while(memSize <= SHMOO_MEMSIZE_MAX )
+ {
+ if(memSize < SHMOO_LIMIT_20KB )
+ {
+ memSize += SHMOO_INCREMENT_1KB;
+ }
+ else if( memSize < SHMOO_LIMIT_50KB)
+ {
+ memSize += SHMOO_INCREMENT_2KB;
+ }
+ else if( memSize < SHMOO_LIMIT_100KB)
+ {
+ memSize += SHMOO_INCREMENT_10KB;
+ }
+ else if( memSize < SHMOO_LIMIT_1MB)
+ {
+ memSize += SHMOO_INCREMENT_100KB;
+ }
+ else if( memSize < SHMOO_LIMIT_16MB)
+ {
+ memSize += SHMOO_INCREMENT_1MB;
+ }
+ else if( memSize < SHMOO_LIMIT_32MB)
+ {
+ memSize += SHMOO_INCREMENT_2MB;
+ }
+ else
+ {
+ memSize += SHMOO_INCREMENT_4MB;
+ }
+
+ memSizes[iteration] = memSize;
+ switch(kind)
+ {
+ case DEVICE_TO_HOST: bandwidths[iteration] +=
testDeviceToHostTransfer(memSizes[iteration], accMode, memMode);
+ break;
+ case HOST_TO_DEVICE: bandwidths[iteration] +=
testHostToDeviceTransfer(memSizes[iteration], accMode, memMode);
+ break;
+ case DEVICE_TO_DEVICE: bandwidths[iteration] +=
testDeviceToDeviceTransfer(memSizes[iteration]);
+ break;
+ }
+ iteration++;
+ stream << ".";
+ }
+ } // Complete the bandwidth computation on all the devices
+
+ //print results
+ stream << endl;
+ printResultsReadable(memSizes, bandwidths, count, kind, accMode,
memMode, (endDevice - startDevice));
+
+ //clean up
+ free(memSizes);
+ free(bandwidths);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// test the bandwidth of a device to host memcopy of a specific size
+///////////////////////////////////////////////////////////////////////////////
+double OpenCLTestBandwidth::testDeviceToHostTransfer(unsigned int memSize,
accessMode accMode, memoryMode memMode)
+{
+ unsigned int timer = 0;
+ double elapsedTimeInSec = 0.0;
+ double bandwidthInMBs = 0.0;
+ unsigned char *h_data = NULL;
+ cl_mem cmPinnedData = NULL;
+ cl_mem cmDevData = NULL;
+ cl_int ciErrNum = CL_SUCCESS;
+
+ //allocate and init host memory, pinned or conventional
+ if(memMode == PINNED)
+ {
+ // Create a host buffer
+ cmPinnedData = clCreateBuffer(cxGPUContext, CL_MEM_READ_WRITE |
CL_MEM_ALLOC_HOST_PTR, memSize, NULL, &ciErrNum);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+
+ // Get a mapped pointer
+ h_data = (unsigned char*)clEnqueueMapBuffer(cqCommandQueue,
cmPinnedData, CL_TRUE, CL_MAP_WRITE, 0, memSize, 0, NULL, NULL, &ciErrNum);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+
+ //initialize
+ for(unsigned int i = 0; i < memSize/sizeof(unsigned char); i++)
+ {
+ h_data[i] = (unsigned char)(i & 0xff);
+ }
+
+ // unmap and make data in the host buffer valid
+ ciErrNum = clEnqueueUnmapMemObject(cqCommandQueue, cmPinnedData,
(void*)h_data, 0, NULL, NULL);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+ }
+ else
+ {
+ // standard host alloc
+ h_data = (unsigned char *)malloc(memSize);
+
+ //initialize
+ for(unsigned int i = 0; i < memSize/sizeof(unsigned char); i++)
+ {
+ h_data[i] = (unsigned char)(i & 0xff);
+ }
+ }
+
+ // allocate device memory
+ cmDevData = clCreateBuffer(cxGPUContext, CL_MEM_READ_WRITE, memSize, NULL,
&ciErrNum);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+
+ // initialize device memory
+ if(memMode == PINNED)
+ {
+ // Get a mapped pointer
+ h_data = (unsigned char*)clEnqueueMapBuffer(cqCommandQueue,
cmPinnedData, CL_TRUE, CL_MAP_WRITE, 0, memSize, 0, NULL, NULL, &ciErrNum);
+
+ ciErrNum = clEnqueueWriteBuffer(cqCommandQueue, cmDevData, CL_FALSE,
0, memSize, h_data, 0, NULL, NULL);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+ }
+ else
+ {
+ ciErrNum = clEnqueueWriteBuffer(cqCommandQueue, cmDevData, CL_FALSE,
0, memSize, h_data, 0, NULL, NULL);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+ }
+ oclCheckError(ciErrNum, CL_SUCCESS);
+
+ // Sync queue to host, start timer 0, and copy data from GPU to Host
+ ciErrNum = clFinish(cqCommandQueue);
+ shrDeltaT(0);
+ if(accMode == DIRECT)
+ {
+ // DIRECT: API access to device buffer
+ for(unsigned int i = 0; i < MEMCOPY_ITERATIONS; i++)
+ {
+ ciErrNum = clEnqueueReadBuffer(cqCommandQueue, cmDevData,
CL_FALSE, 0, memSize, h_data, 0, NULL, NULL);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+ }
+ ciErrNum = clFinish(cqCommandQueue);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+ }
+ else
+ {
+ // MAPPED: mapped pointers to device buffer for conventional pointer
access
+ void* dm_idata = clEnqueueMapBuffer(cqCommandQueue, cmDevData,
CL_TRUE, CL_MAP_WRITE, 0, memSize, 0, NULL, NULL, &ciErrNum);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+ for(unsigned int i = 0; i < MEMCOPY_ITERATIONS; i++)
+ {
+ memcpy(h_data, dm_idata, memSize);
+ }
+ ciErrNum = clEnqueueUnmapMemObject(cqCommandQueue, cmDevData,
dm_idata, 0, NULL, NULL);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+ }
+
+ //get the the elapsed time in seconds
+ elapsedTimeInSec = shrDeltaT(0);
+
+ //calculate bandwidth in MB/s
+ bandwidthInMBs = ((double)memSize * (double)MEMCOPY_ITERATIONS) /
(elapsedTimeInSec * (double)(1 << 20));
+
+ //clean up memory
+ if(cmDevData)clReleaseMemObject(cmDevData);
+ if(cmPinnedData)
+ {
+ clEnqueueUnmapMemObject(cqCommandQueue, cmPinnedData,
(void*)h_data, 0, NULL, NULL);
+ clReleaseMemObject(cmPinnedData);
+ }
+ h_data = NULL;
+
+ return bandwidthInMBs;
+}
+///////////////////////////////////////////////////////////////////////////////
+// test the bandwidth of a device to host memcopy of a specific size
+///////////////////////////////////////////////////////////////////////////////
+double OpenCLTestBandwidth::testHostToDeviceTransfer(unsigned int memSize,
accessMode accMode, memoryMode memMode)
+{
+ unsigned int timer = 0;
+ double elapsedTimeInSec = 0.0;
+ double bandwidthInMBs = 0.0;
+ unsigned char* h_data = NULL;
+ cl_mem cmPinnedData = NULL;
+ cl_mem cmDevData = NULL;
+ cl_int ciErrNum = CL_SUCCESS;
+
+ // Allocate and init host memory, pinned or conventional
+ if(memMode == PINNED)
+ {
+ // Create a host buffer
+ cmPinnedData = clCreateBuffer(cxGPUContext, CL_MEM_READ_WRITE |
CL_MEM_ALLOC_HOST_PTR, memSize, NULL, &ciErrNum);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+
+ // Get a mapped pointer
+ h_data = (unsigned char*)clEnqueueMapBuffer(cqCommandQueue,
cmPinnedData, CL_TRUE, CL_MAP_WRITE, 0, memSize, 0, NULL, NULL, &ciErrNum);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+
+ //initialize
+ for(unsigned int i = 0; i < memSize/sizeof(unsigned char); i++)
+ {
+ h_data[i] = (unsigned char)(i & 0xff);
+ }
+
+ // unmap and make data in the host buffer valid
+ ciErrNum = clEnqueueUnmapMemObject(cqCommandQueue, cmPinnedData,
(void*)h_data, 0, NULL, NULL);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+ }
+ else
+ {
+ // standard host alloc
+ h_data = (unsigned char *)malloc(memSize);
+
+ //initialize
+ for(unsigned int i = 0; i < memSize/sizeof(unsigned char); i++)
+ {
+ h_data[i] = (unsigned char)(i & 0xff);
+ }
+ }
+
+ // allocate device memory
+ cmDevData = clCreateBuffer(cxGPUContext, CL_MEM_READ_WRITE, memSize, NULL,
&ciErrNum);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+
+ // Sync queue to host, start timer 0, and copy data from Host to GPU
+ clFinish(cqCommandQueue);
+ shrDeltaT(0);
+ if(accMode == DIRECT)
+ {
+ if(memMode == PINNED)
+ {
+ // Get a mapped pointer
+ h_data = (unsigned char*)clEnqueueMapBuffer(cqCommandQueue,
cmPinnedData, CL_TRUE, CL_MAP_WRITE, 0, memSize, 0, NULL, NULL, &ciErrNum);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+ }
+
+ // DIRECT: API access to device buffer
+ for(unsigned int i = 0; i < MEMCOPY_ITERATIONS; i++)
+ {
+ ciErrNum = clEnqueueWriteBuffer(cqCommandQueue, cmDevData,
CL_FALSE, 0, memSize, h_data, 0, NULL, NULL);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+ }
+ ciErrNum = clFinish(cqCommandQueue);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+ }
+ else
+ {
+ // MAPPED: mapped pointers to device buffer and conventional pointer
access
+ void* dm_idata = clEnqueueMapBuffer(cqCommandQueue, cmDevData,
CL_TRUE, CL_MAP_READ, 0, memSize, 0, NULL, NULL, &ciErrNum);
+ for(unsigned int i = 0; i < MEMCOPY_ITERATIONS; i++)
+ {
+ memcpy(dm_idata, h_data, memSize);
+ }
+ ciErrNum = clEnqueueUnmapMemObject(cqCommandQueue, cmDevData,
dm_idata, 0, NULL, NULL);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+ }
+
+ //get the the elapsed time in seconds
+ elapsedTimeInSec = shrDeltaT(0);
+
+ //calculate bandwidth in MB/s
+ bandwidthInMBs = ((double)memSize *
(double)MEMCOPY_ITERATIONS)/(elapsedTimeInSec * (double)(1 << 20));
+
+ //clean up memory
+ if(cmDevData)clReleaseMemObject(cmDevData);
+ if(cmPinnedData)
+ {
+ clEnqueueUnmapMemObject(cqCommandQueue, cmPinnedData,
(void*)h_data, 0, NULL, NULL);
+ clReleaseMemObject(cmPinnedData);
+ }
+ h_data = NULL;
+
+ return bandwidthInMBs;
+}
+///////////////////////////////////////////////////////////////////////////////
+// test the bandwidth of a device to host memcopy of a specific size
+///////////////////////////////////////////////////////////////////////////////
+double OpenCLTestBandwidth::testDeviceToDeviceTransfer(unsigned int memSize)
+{
+ unsigned int timer = 0;
+ double elapsedTimeInSec = 0.0;
+ double bandwidthInMBs = 0.0;
+ unsigned char* h_idata = NULL;
+ cl_int ciErrNum = CL_SUCCESS;
+
+ //allocate host memory
+ h_idata = (unsigned char *)malloc( memSize );
+
+ //initialize the memory
+ for(unsigned int i = 0; i < memSize/sizeof(unsigned char); i++)
+ {
+ h_idata[i] = (unsigned char) (i & 0xff);
+ }
+
+ // allocate device input and output memory and initialize the device input
memory
+ cl_mem d_idata = clCreateBuffer(cxGPUContext, CL_MEM_READ_ONLY, memSize,
NULL, &ciErrNum);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+ cl_mem d_odata = clCreateBuffer(cxGPUContext, CL_MEM_WRITE_ONLY, memSize,
NULL, &ciErrNum);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+ ciErrNum = clEnqueueWriteBuffer(cqCommandQueue, d_idata, CL_TRUE, 0,
memSize, h_idata, 0, NULL, NULL);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+
+ // Sync queue to host, start timer 0, and copy data from one GPU buffer to
another GPU bufffer
+ clFinish(cqCommandQueue);
+ shrDeltaT(0);
+ for(unsigned int i = 0; i < MEMCOPY_ITERATIONS; i++)
+ {
+ ciErrNum = clEnqueueCopyBuffer(cqCommandQueue, d_idata, d_odata, 0, 0,
memSize, 0, NULL, NULL);
+ oclCheckError(ciErrNum, CL_SUCCESS);
+ }
+
+ // Sync with GPU
+ clFinish(cqCommandQueue);
+
+ //get the the elapsed time in seconds
+ elapsedTimeInSec = shrDeltaT(0);
+
+ // Calculate bandwidth in MB/s
+ // This is for kernels that read and write GMEM simultaneously
+ // Obtained Throughput for unidirectional block copies will be 1/2 of
this #
+ bandwidthInMBs = 2.0 * ((double)memSize *
(double)MEMCOPY_ITERATIONS)/(elapsedTimeInSec * (double)(1 << 20));
+
+ //clean up memory on host and device
+ free(h_idata);
+ clReleaseMemObject(d_idata);
+ clReleaseMemObject(d_odata);
+
+ return bandwidthInMBs;
+}
+
+/////////////////////////////////////////////////////////
+//print results in an easily read format
+////////////////////////////////////////////////////////
+void OpenCLTestBandwidth::printResultsReadable(unsigned int *memSizes, double*
bandwidths, unsigned int count, memcpyKind kind, accessMode accMode, memoryMode
memMode, int iNumDevs)
+{
+ // log config information
+ if (kind == DEVICE_TO_DEVICE)
+ {
+ stream << "== Device to Device Bandwidth, Device(s) " << iNumDevs << "
==" << endl;
+ }
+ else
+ {
+ if (kind == DEVICE_TO_HOST)
+ {
+ stream << "== Device to Host Bandwidth, Device(s) " << iNumDevs <<
" ==" << endl;
+ }
+ else if (kind == HOST_TO_DEVICE)
+ {
+ stream << "== Host to Device Bandwidth, Device(s) " << iNumDevs <<
" ==" << endl;
+ }
+ if(memMode == PAGEABLE)
+ {
+ stream << "(Paged memory";
+ }
+ else if (memMode == PINNED)
+ {
+ stream << "(Pinned memory";
+ }
+ if(accMode == DIRECT)
+ {
+ stream << ", direct access)" << endl;
+ }
+ else if (accMode == MAPPED)
+ {
+ stream << ", mapped access)" << endl;
+ }
+ }
+
+ stream << "> Transfer Size (Bytes) : Bandwidth(MB/s)" << endl;
+ unsigned int i;
+ for(i = 0; i < count; i++)
+ {
+ stream << "> " << memSizes[i] << " : " << bandwidths[i] <<
endl;
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
This SF.net email is sponsored by
Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev
_______________________________________________
Rigsofrods-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rigsofrods-devel