I was coding away on an assignment when I ran into a conundrum: I was getting weird results when attempting to copy data onto the device. There would be instances when arrays copied onto the device would be accessible, yet inaccessible during another run.
The fact I'm coding CUDA kernels on OS X gives way to a dilemma: cuda-gdb is not available (yet) on OS X. I have to rely on old school debugging techniques ... a code walk through and print statements! After numerous tests and frustrations ... I figured out I was running into a problem with global memory:
marklagatuz$ /Developer/GPU\ Computing/C/bin/darwin/release/deviceQuery
Device 0: "GeForce 9400M"
Total amount of global memory: 265945088 bytes
The above reads approximately 265MB of global memory. I had 4 arrays consisting of 67MB each being copied onto the device. I was clearly running into memory issues. This would explain why each time a different array would cause problems.
Lesson learned: Check your device(s) limitations before coding away! Then again ... you should be doing that anyways!
Monday, June 21, 2010
Tuesday, June 15, 2010
Learned Something New (or actually a review of something old)!
Since I'm forcing myself to think in terms of OO (Object Orientation), I forgot that computers are still 1 and 0's! As I'm reading code to understand design patterns, algorithms, and methods others folks are using, I came across something I've never used before (at least in my own code): shift operators.
(1 << 24) == 0001 1111 1111 1111 1111 1111 1111
- <<
- >>
(1 << 24) == 0001 1111 1111 1111 1111 1111 1111
CUDA + THRUST + Eclipse
Quickstart
Assumptions: A working CUDA environment (I'm using OS X for this example).
2. Select a location and unzip the thrust library. You can unzip the library into the default cuda include location (/usr/local/cuda/include). I prefer to unzip the library in my home directory, (specifically the Downloads directory) but it's up to the user!
3. Add the libraries within your project in Eclipse
The code compiled after removing /thrust from the -I on the command line (absolute path up to the thrust library).
--
References:
1. Thrust QuickStartGuide
Assumptions: A working CUDA environment (I'm using OS X for this example).
- nvcc --version --> should display CUDA Version, built date, and version of tools installed.
- ./deviceQuery from /Developer/GPU Computing/C/bin/darwin/release (for OS X) should produce output for your device
2. Select a location and unzip the thrust library. You can unzip the library into the default cuda include location (/usr/local/cuda/include). I prefer to unzip the library in my home directory, (specifically the Downloads directory) but it's up to the user!
- unzip thrust-v1.3.0.zip
3. Add the libraries within your project in Eclipse
- Project Name --> Properties
- C/C++ Build --> Settings
- CUDA NVCC Compiler --> Includes
- Add (On the same line as Include Paths - green + button)
The code compiled after removing /thrust from the -I on the command line (absolute path up to the thrust library).
--
References:
1. Thrust QuickStartGuide
- http://code.google.com/p/thrust/wiki/QuickStartGuide
Thursday, June 10, 2010
CUDA Quick Tips, Reference, and Cheat Sheets
Here are some quick tips and references I strung together while I'm learning CUDA
A. Size of a Grid:
B. Size of a Block:
C. Thread Local Index within its block (assuming a 1Dimensional Block):
D. Block Local Index
E. Thread Global Index across the entire grid (assuming a 1 Dimensional Grid):
F. Thread Local Index within its block (assuming a 2Dimensional Block):
F-1.Obtain current column index (assuming you have a N x N Block):
Quick Example
N = 1024. You have to process N x N elements (1024 x 1024). You could decompose the grid as so: You could set the blockSize to 64. Then gridSize = numElements / blockSize --> gridSize = 1024 / 64 = 16. Maybe not the most efficient way, but since it's only an example it will do!
So your grid is composed of 4096 Blocks (64 x 64), and each Block is composed of 256 threads (16 x 16).
Total Blocks * Total Threasd per Block = 4096 * 256 = 1,048576 = N * N = 1024 * 1024.
To process each element serially, you would probably have a nested for loop:
To access each element for processing in CUDA (assuming you are storing results in a 1D array):
More quick tips in the future ...
A. Size of a Grid:
- gridDim.x (1Dimensional)
- gridDim.x (2Dimensional, assuming a N x N Grid)
B. Size of a Block:
- blockDim.x (1Dimensional)
- blockDim.x (2Dimensional, assuming a N x N Block)
C. Thread Local Index within its block (assuming a 1Dimensional Block):
- threadIdx.x
D. Block Local Index
- blockIdx.x (1Dimensional)
- blockIdx.x (2Dimensional) --> Current Column Index (Length) of a N x N Block
- blockIdx.y (2Dimensional) --> Current Row Index (Height) of a N x N Block
E. Thread Global Index across the entire grid (assuming a 1 Dimensional Grid):
- (blockDim.x * blockIdx.x) + threadIdx.x
F. Thread Local Index within its block (assuming a 2Dimensional Block):
F-1.Obtain current column index (assuming you have a N x N Block):
- (blockIdx.x * blockDimx.x) + threadIdx.x
- (blockIdx.y * blockDimx.x) + threadIdx.y
Quick Example
N = 1024. You have to process N x N elements (1024 x 1024). You could decompose the grid as so: You could set the blockSize to 64. Then gridSize = numElements / blockSize --> gridSize = 1024 / 64 = 16. Maybe not the most efficient way, but since it's only an example it will do!
So your grid is composed of 4096 Blocks (64 x 64), and each Block is composed of 256 threads (16 x 16).
Total Blocks * Total Threasd per Block = 4096 * 256 = 1,048576 = N * N = 1024 * 1024.
To process each element serially, you would probably have a nested for loop:
for (each col)
for (each row)
process element
To access each element for processing in CUDA (assuming you are storing results in a 1D array):
- (Global Row * Number of Elements) + Global Column
- Global Row = (blockIdx.y * blockDimx.x + threadIdx.y)
- Global Column = (blockIdx.x * blockDimx.x + threadIdx.x)
- Number of Elements = N = Number of elements Length wise (1024 in my example)
More quick tips in the future ...
Tuesday, June 1, 2010
Quickstart: CUDA using Bayreuth University CUDA Toolchain for Eclipse
I've been trolling through Google for a simple solution in integrating CUDA with Eclipse, and found a University which built an Eclipse plugin. This is a fantastic solution because my previous attempts required me to create my own Makefile (which partially defeats the purpose of using Eclipse!)
Here is my Quickstart for the plugin
Assumptions:
*** UPDATE ***
When attempting to build my project, I was getting the following error message during the build phase:
make all
Building target: CUDAToolchainProject
ld: unknown option: -oCUDAToolchainProject
I tracked the problem down to not having "whitespaces" in between the following:
Invoking: C++ Linker
g++ -L/usr/local/cuda/lib -o "CUDAToolchainProject" ./src/cu_mandelbrotCUDA_D.o ./src/cu_mandelbrotCUDA_H.o -lcudart
ld: warning: in ./src/cu_mandelbrotCUDA_D.o, file is not of required architecture
ld: warning: in ./src/cu_mandelbrotCUDA_H.o, file is not of required architecture
ld: warning: in /usr/local/cuda/lib/libcudart.dylib, file is not of required architecture
Undefined symbols:
"_main", referenced from:
start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [CUDAToolchainProject] Error 1
To mitigate this problem ... I changed the C++ Linker from g++ to nvcc
The build phase completed successfully and an executable was generated!
The next steps are optional (If you want to follow Eclipse's general project structure, follow the next steps
4. Create Source Folders (Trivial)
Resources
1. Bayreuth University Website
Here is my Quickstart for the plugin
Assumptions:
- A fully functional C/C++ working environment (within the Eclipse IDE and on the command line)
- A fully functional CUDA environment (including the CUDA Driver, Toolkit, and SDK
- This assumes you are using OS X (Linux should be quite similar)
- Help --> Install New Software -->
- Name =
( for me) - Location = http://www.ai3.inf.uni-bayreuth.de/software/eclipsecudaqt/updates
- Click on Uncategorized --> Toolchains for CUDA and QT Development
- Accept the License Agreement
- Restart Eclipse
- Go to Eclipse --> Preferences
- Click on C/C++ --> Environment
- Under Environment variables to set --> click Add
- Name = PATH (Note: Make sure PATH are all upper case)
- Value = /usr/local/cuda/bin
- Apply and OK
- Ctrl + mouse click --> New --> C++ project
- Under Project type box --> Executable --> select Empty Project
- Name your project
- Uncheck the following: Show project types and toolchains only if they are supported on the platform
- Under Toolchains --> select CUDA Toolchain
- Click Next
- Click on Advanced Settings
- Under C/C++ Build -->Environment --> Confirm PATH is set from previous step (should be USER: PREFS under Origin Column)
- Under C/C++ Build --> Settings --> Tool Settings Tab --> CUDA NVCC Compiler --> Includes --> add /usr/local/cuda/include
- Under C/C++ Build --> C++ Linker --> change Command from g++ to nvcc
- Under C/C++ Build --> C++ Linker --> Libraries --> add cudart to Libraries (-l) and add /usr/local/cuda/lib to Library search path (-L)
- Apply and OK
*** UPDATE ***
When attempting to build my project, I was getting the following error message during the build phase:
make all
Building target: CUDAToolchainProject
ld: unknown option: -oCUDAToolchainProject
I tracked the problem down to not having "whitespaces" in between the following:
- ${OUTPUT_FLAG}${OUTPUT_PREFIX}${OUTPUT}
- This is located at -->
--> Properties --> C/C++ Build --> Settings --> C++ Linker - Under Expert Settings --> Command line pattern
- ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX} ${OUTPUT} ${INPUTS}
Invoking: C++ Linker
g++ -L/usr/local/cuda/lib -o "CUDAToolchainProject" ./src/cu_mandelbrotCUDA_D.o ./src/cu_mandelbrotCUDA_H.o -lcudart
ld: warning: in ./src/cu_mandelbrotCUDA_D.o, file is not of required architecture
ld: warning: in ./src/cu_mandelbrotCUDA_H.o, file is not of required architecture
ld: warning: in /usr/local/cuda/lib/libcudart.dylib, file is not of required architecture
Undefined symbols:
"_main", referenced from:
start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [CUDAToolchainProject] Error 1
To mitigate this problem ... I changed the C++ Linker from g++ to nvcc
- Properties --> C/C++ Build --> Settings --> C++ Linker
- Command --> change from g++ to nvcc
The build phase completed successfully and an executable was generated!
The next steps are optional (If you want to follow Eclipse's general project structure, follow the next steps
4. Create Source Folders (Trivial)
- Ctrl + mouse click --> New --> Source Folder
- Name your folder
Resources
1. Bayreuth University Website
- http://www.ai3.inf.uni-bayreuth.de/software/eclipsecudaqt/updates
- http://forums.nvidia.com/index.php?showtopic=160564
- http://lifeofaprogrammergeek.blogspot.com/2008/07/using-eclipse-for-cuda-development.html
Labels:
Bayreuth University,
cuda,
Eclipse,
Eclipse CUDA Plugin,
Eclipse plugin,
OS X
Tuesday, May 25, 2010
Example of Eclipse + CUDA Integration
I'm tired of using vi to edit my .cu source files, so I decided to attempt to integrate CUDA with the Eclipse IDE.
Right off the back, when you build your CUDA project within Eclipse, it will FAIL! Determined not to use vi, I trolled Google for help. Additionally, I attempted to mimic a build similar to a simple Hello World Project.
Assumptions: Drop this Makefile (located after the Example Project Creation) at the top of your Project Directory to have a successful build.
MAC OS X
1. Create a new C++ Project
2. Create an Empty Project
3. Click Advanced Settings
4. Remove Automatic Makefile Generation
5. Apply and OK
6. Finish
7. Create a source directory within your project
8. Create C++ source files within the source folder
9. Create a regular file for the associated Makefile
10. Copy the example Makefile from below into your Project
(using your own information)
##############################################
#
# Makefile for CUDA
#
# A hack created by Mark Lagatuz to compile .cu files within Eclipse
#
# This makefile assumes you separate the device and host code into
# separate files:
#
# HOST: _H appended to file name (code_H.cu)
# DEVICE: _D appended to file name (code_D.cu)
#
# Replace the following with your own information:
#
# CUDA_INSTALL_PATH: /path/to/your/cuda/installation
# PROGRAM: Name of Executable
#
##############################################
# CUDA Installation Path
CUDA_INSTALL_PATH = /usr/local/cuda
# Source Folder (Relative to where Makefile is located)
SRC_FOLDER = src
# Compiler
NVCC = $(CUDA_INSTALL_PATH)/bin/nvcc
# Includes
INCLUDE = $(CUDA_INSTALL_PATH)/include
# Program or Executable
PROGRAM = mandelbrotCUDA
# Device Code
DEVICE = _D
# Host Code
HOST = _H
all : $(PROGRAM)
# Create Executable by linking *.o (host and device object's)
$(PROGRAM) : $(PROGRAM)$(DEVICE).o $(PROGRAM)$(HOST).o
$(NVCC) -o $(PROGRAM) $^
# Compile device code to an object
$(PROGRAM)$(DEVICE).o : $(SRC_FOLDER)/$(PROGRAM)$(DEVICE).cu
$(NVCC) -I $(INCLUDE) -o $@ -c $< # Compile host code to an object $(PROGRAM)$(HOST).o : $(SRC_FOLDER)/$(PROGRAM)$(HOST).cu $(NVCC) -I $(INCLUDE) -o $@ -c $< # Remove *.o files and executables clean : rm *.o $(PROGRAM) -- Resources
1. MAC OS X
2. Life of a Programmer Greek
3. How to set up CUDA in Eclipse
Right off the back, when you build your CUDA project within Eclipse, it will FAIL! Determined not to use vi, I trolled Google for help. Additionally, I attempted to mimic a build similar to a simple Hello World Project.
Assumptions: Drop this Makefile (located after the Example Project Creation) at the top of your Project Directory to have a successful build.
MAC OS X
1. Create a new C++ Project
- ctrl + mouse click --> New --> C++ Project
2. Create an Empty Project
- Select Empty Project
- Create a project name
- Click Next
3. Click Advanced Settings
4. Remove Automatic Makefile Generation
- C/C++ Build --> Makefile Generation
- Uncheck Generate Makefile automatically
5. Apply and OK
6. Finish
7. Create a source directory within your project
- ctrl+mouse click on project --> New --> Source Folder
- Name the folder
- Finish
8. Create C++ source files within the source folder
9. Create a regular file for the associated Makefile
- ctrl+mouse click on the project --> New -->File
- Name the file Makefile
10. Copy the example Makefile from below into your Project
(using your own information)
##############################################
#
# Makefile for CUDA
#
# A hack created by Mark Lagatuz to compile .cu files within Eclipse
#
# This makefile assumes you separate the device and host code into
# separate files:
#
# HOST: _H appended to file name (code_H.cu)
# DEVICE: _D appended to file name (code_D.cu)
#
# Replace the following with your own information:
#
# CUDA_INSTALL_PATH: /path/to/your/cuda/installation
# PROGRAM: Name of Executable
#
##############################################
# CUDA Installation Path
CUDA_INSTALL_PATH = /usr/local/cuda
# Source Folder (Relative to where Makefile is located)
SRC_FOLDER = src
# Compiler
NVCC = $(CUDA_INSTALL_PATH)/bin/nvcc
# Includes
INCLUDE = $(CUDA_INSTALL_PATH)/include
# Program or Executable
PROGRAM = mandelbrotCUDA
# Device Code
DEVICE = _D
# Host Code
HOST = _H
all : $(PROGRAM)
# Create Executable by linking *.o (host and device object's)
$(PROGRAM) : $(PROGRAM)$(DEVICE).o $(PROGRAM)$(HOST).o
$(NVCC) -o $(PROGRAM) $^
# Compile device code to an object
$(PROGRAM)$(DEVICE).o : $(SRC_FOLDER)/$(PROGRAM)$(DEVICE).cu
$(NVCC) -I $(INCLUDE) -o $@ -c $< # Compile host code to an object $(PROGRAM)$(HOST).o : $(SRC_FOLDER)/$(PROGRAM)$(HOST).cu $(NVCC) -I $(INCLUDE) -o $@ -c $< # Remove *.o files and executables clean : rm *.o $(PROGRAM) -- Resources
1. MAC OS X
- /Developer/GPU Computing/C/common/common.mk (I utilized this file to help build my Makefile
2. Life of a Programmer Greek
- http://lifeofaprogrammergeek.blogspot.com/2008/07/using-eclipse-for-cuda-development.html
3. How to set up CUDA in Eclipse
- http://imonad.com/blog/how-to-set-cuda-in-eclipse/
Parallel Tools Platform (PTP) Plugin for Eclipse + OpenMPI
Quickstart
Assumption: A working Eclipse Development Environment successfully installed (JDT, J2EE, CDT).
1. Install the CDT (if not already installed). Replace Galileo with your version of Eclipse (Europa)
2. Install the PTP Plugin. Replace Galileo with your version of Eclipse (Europa), and Insert your own name for the NAME field
3. Install the following software (This is the minimal plugins I use for OpenMPI):
You now have a fully functional environment to begin using Eclipse as your Parallel Computing IDE!
A few more steps are necessary to actually compile and run your OpenMPI code ...
Specify the MPI include path
1. Within the Eclipse IDE
2. Navigate to the location of your include files for OpenMPI
6. Apply and OK
7. For some odd reason, the above steps only cover C, not C++. You will need to complete the following for C++
Adding a Resource Manager
This allows you to submit jobs onto your localhost. This assumes you will be running only on your own workstation, and not on a cluster.
1. Switch to the Parallel Runtime Perspective
2. Right click on the Resource Manager
3. Click on Resource Manager
4. Select Resource Manager Type: for this example it will be OpenMPI. This will be different if you have another version of MPI (MPICH).
5. During the next couple of screens, selecting the default options will suffice. You would deviate if you're working on a cluster
6. Start Resource Manager
--
Resources
1. Setup for MPI tools within the Parallel Language Development Tools
2. Trial & Error
Assumption: A working Eclipse Development Environment successfully installed (JDT, J2EE, CDT).
1. Install the CDT (if not already installed). Replace Galileo with your version of Eclipse (Europa)
- Help --> Install New Software
- Work With --> Galileo --> http://download.eclipse.org/release/galileo
- Programming Languages --> Eclipse C/C++ Development Tools
2. Install the PTP Plugin. Replace Galileo with your version of Eclipse (Europa), and Insert your own name for the NAME field
- Help --> Install New Software
- Work With --> Add
- PTP (NAME)
- http://download.eclipse.org/tools/ptp/releases/galileo (Location)
3. Install the following software (This is the minimal plugins I use for OpenMPI):
- Parallel Tools Platform: Parallel Tools Platform Core
- Parallel Tools Platform: Parallel Tools Platform End-User
- Parallel Tools Platform: PTP Common Utilities
- Parallel Tools Platform: PTP Parallel Language Development Tools
- Parallel Tools Platform: PTP Scalable Debug Manager
- Parallel Tools Platform: PTP Support for OpenMPI
You now have a fully functional environment to begin using Eclipse as your Parallel Computing IDE!
A few more steps are necessary to actually compile and run your OpenMPI code ...
Specify the MPI include path
1. Within the Eclipse IDE
- Window --> Preferences (OS X: Eclipse --> Preferences)
- Select Parallel Tools
- Parallel Language Development Tools --> MPI
- Under MPI --> Include Paths --> New
2. Navigate to the location of your include files for OpenMPI
- /home/mlagatuz/Desktop/openmpi/include (Red Hat Enterprise Linux)
- /usr/include (OS X) --> If I used the GUI, I needed to select /Developer/SDKs/MacOSX10.6.sdk/usr/include
6. Apply and OK
7. For some odd reason, the above steps only cover C, not C++. You will need to complete the following for C++
- Right-Click on your project name --> Select Properties --> C/C++ General --> Paths and Symbols
- Under Includes Tab --> Select GNU C++ --> Add
- Navigate to your include files for OpenMPI (same as above)
- Apply and OK
Adding a Resource Manager
This allows you to submit jobs onto your localhost. This assumes you will be running only on your own workstation, and not on a cluster.
1. Switch to the Parallel Runtime Perspective
2. Right click on the Resource Manager
3. Click on Resource Manager
4. Select Resource Manager Type: for this example it will be OpenMPI. This will be different if you have another version of MPI (MPICH).
5. During the next couple of screens, selecting the default options will suffice. You would deviate if you're working on a cluster
6. Start Resource Manager
--
Resources
1. Setup for MPI tools within the Parallel Language Development Tools
- http://www.eclipse.org/ptp/documentation/org.eclipse.ptp.pldt.help/html/setup.html
2. Trial & Error
Subscribe to:
Posts (Atom)
