CUDA 13.2 samples update (#432)

- Added Python samples for CUDA Python 1.0 release
- Renamed top-level `Samples` directory to `cpp` to accommodate Python samples.
This commit is contained in:
Dheemanth
2026-05-13 15:13:18 -07:00
committed by GitHub
parent a4526d5229
commit aeab82ff30
2072 changed files with 15077 additions and 1970 deletions

View File

@@ -0,0 +1,18 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"${workspaceFolder}/../../../Common"
],
"defines": [],
"compilerPath": "/usr/local/cuda/bin/nvcc",
"cStandard": "gnu17",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-gcc-x64",
"configurationProvider": "ms-vscode.makefile-tools"
}
],
"version": 4
}

View File

@@ -0,0 +1,7 @@
{
"recommendations": [
"nvidia.nsight-vscode-edition",
"ms-vscode.cpptools",
"ms-vscode.makefile-tools"
]
}

View File

@@ -0,0 +1,96 @@
cmake_minimum_required(VERSION 3.20)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/Modules")
project(Mandelbrot LANGUAGES C CXX CUDA)
find_package(CUDAToolkit REQUIRED)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_CUDA_ARCHITECTURES 75 80 86 87 89 90 100 110 120)
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Wno-deprecated-gpu-targets")
if(ENABLE_CUDA_DEBUG)
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -G") # enable cuda-gdb (may significantly affect performance on some targets)
else()
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -lineinfo") # add line information to all builds for debug tools (exclusive to -G option)
endif()
# Include directories and libraries
include_directories(../../../Common)
if(WIN32)
set(PC_GLUT_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/../../../Common")
set(PC_GLUT_LIBRARY_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/../../../Common/lib/x64")
# The GLEW library built on Windows on Arm system is named as glew32.lib/glew32.dll by default.
if(EXISTS "${PC_GLUT_LIBRARY_DIRS}/glew32.lib")
set(GLEW_LIB_NAME "glew32")
else()
set(GLEW_LIB_NAME "glew64")
endif()
endif()
find_package(OpenGL)
find_package(GLUT)
# Source file
if(${OpenGL_FOUND})
if (${GLUT_FOUND})
# Add target for Mandelbrot
add_executable(Mandelbrot Mandelbrot_cuda.cu Mandelbrot_gold.cpp Mandelbrot.cpp)
target_compile_options(Mandelbrot PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:--extended-lambda>)
target_compile_features(Mandelbrot PRIVATE cxx_std_17 cuda_std_17)
set_target_properties(Mandelbrot PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
target_include_directories(Mandelbrot PUBLIC
${OPENGL_INCLUDE_DIR}
${CUDAToolkit_INCLUDE_DIRS}
${GLUT_INCLUDE_DIRS}
)
target_link_libraries(Mandelbrot
${OPENGL_LIBRARIES}
${GLUT_LIBRARIES}
)
# Copy data files to the output directory
add_custom_command(TARGET Mandelbrot POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_SOURCE_DIR}/data
${CMAKE_CURRENT_BINARY_DIR}/data
)
if(WIN32)
target_link_libraries(Mandelbrot
${PC_GLUT_LIBRARY_DIRS}/freeglut.lib
${PC_GLUT_LIBRARY_DIRS}/${GLEW_LIB_NAME}.lib
)
add_custom_command(TARGET Mandelbrot
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/../../../bin/win64/$<CONFIGURATION>/freeglut.dll
${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>
)
add_custom_command(TARGET Mandelbrot
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/../../../bin/win64/$<CONFIGURATION>/${GLEW_LIB_NAME}.dll
${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>
)
endif()
else()
message(STATUS "GLUT not found - will not build sample 'Mandelbrot'")
endif()
else()
message(STATUS "OpenGL not found - will not build sample 'Mandelbrot'")
endif()
# Include installation configuration
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/InstallSamples.cmake)
setup_samples_install()

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,529 @@
/* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of NVIDIA CORPORATION nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include "Mandelbrot_kernel.cuh"
#include "Mandelbrot_kernel.h"
#include "helper_cuda.h"
// The Mandelbrot CUDA GPU thread function
template <class T>
__global__ void Mandelbrot0(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const T xOff,
const T yOff,
const T xJP,
const T yJP,
const T scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const int gridWidth,
const int numBlocks,
const bool isJ)
{
// loop until all blocks completed
for (unsigned int blockIndex = blockIdx.x; blockIndex < numBlocks; blockIndex += gridDim.x) {
unsigned int blockX = blockIndex % gridWidth;
unsigned int blockY = blockIndex / gridWidth;
// process this block
const int ix = blockDim.x * blockX + threadIdx.x;
const int iy = blockDim.y * blockY + threadIdx.y;
if ((ix < imageW) && (iy < imageH)) {
// Calculate the location
const T xPos = (T)ix * scale + xOff;
const T yPos = (T)iy * scale + yOff;
// Calculate the Mandelbrot index for the current location
int m = CalcMandelbrot<T>(xPos, yPos, xJP, yJP, crunch, isJ);
// int m = blockIdx.x; // uncomment to see scheduling
// order
m = m > 0 ? crunch - m : 0;
// Convert the Mandelbrot index into a color
uchar4 color;
if (m) {
m += animationFrame;
color.x = m * colors.x;
color.y = m * colors.y;
color.z = m * colors.z;
}
else {
color.x = 0;
color.y = 0;
color.z = 0;
}
// Output the pixel
int pixel = imageW * iy + ix;
if (frame == 0) {
color.w = 0;
dst[pixel] = color;
}
else {
int frame1 = frame + 1;
int frame2 = frame1 / 2;
dst[pixel].x = (dst[pixel].x * frame + color.x + frame2) / frame1;
dst[pixel].y = (dst[pixel].y * frame + color.y + frame2) / frame1;
dst[pixel].z = (dst[pixel].z * frame + color.z + frame2) / frame1;
}
}
}
} // Mandelbrot0
// The Mandelbrot CUDA GPU thread function (double single version)
__global__ void MandelbrotDS0(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const float xOff0,
const float xOff1,
const float yOff0,
const float yOff1,
const float xJP,
const float yJP,
const float scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const int gridWidth,
const int numBlocks,
const bool isJ)
{
// loop until all blocks completed
for (unsigned int blockIndex = blockIdx.x; blockIndex < numBlocks; blockIndex += gridDim.x) {
unsigned int blockX = blockIndex % gridWidth;
unsigned int blockY = blockIndex / gridWidth;
// process this block
const int ix = blockDim.x * blockX + threadIdx.x;
const int iy = blockDim.y * blockY + threadIdx.y;
if ((ix < imageW) && (iy < imageH)) {
// Calculate the location
float xPos0 = (float)ix * scale;
float xPos1 = 0.0f;
float yPos0 = (float)iy * scale;
float yPos1 = 0.0f;
dsadd(xPos0, xPos1, xPos0, xPos1, xOff0, xOff1);
dsadd(yPos0, yPos1, yPos0, yPos1, yOff0, yOff1);
// Calculate the Mandelbrot index for the current location
int m = CalcMandelbrotDS(xPos0, xPos1, yPos0, yPos1, xJP, yJP, crunch, isJ);
m = m > 0 ? crunch - m : 0;
// Convert the Mandelbrot index into a color
uchar4 color;
if (m) {
m += animationFrame;
color.x = m * colors.x;
color.y = m * colors.y;
color.z = m * colors.z;
}
else {
color.x = 0;
color.y = 0;
color.z = 0;
}
// Output the pixel
int pixel = imageW * iy + ix;
if (frame == 0) {
color.w = 0;
dst[pixel] = color;
}
else {
int frame1 = frame + 1;
int frame2 = frame1 / 2;
dst[pixel].x = (dst[pixel].x * frame + color.x + frame2) / frame1;
dst[pixel].y = (dst[pixel].y * frame + color.y + frame2) / frame1;
dst[pixel].z = (dst[pixel].z * frame + color.z + frame2) / frame1;
}
}
}
} // MandelbrotDS0
// The Mandelbrot secondary AA pass CUDA GPU thread function
template <class T>
__global__ void Mandelbrot1(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const T xOff,
const T yOff,
const T xJP,
const T yJP,
const T scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const int gridWidth,
const int numBlocks,
const bool isJ)
{
// loop until all blocks completed
for (unsigned int blockIndex = blockIdx.x; blockIndex < numBlocks; blockIndex += gridDim.x) {
unsigned int blockX = blockIndex % gridWidth;
unsigned int blockY = blockIndex / gridWidth;
// process this block
const int ix = blockDim.x * blockX + threadIdx.x;
const int iy = blockDim.y * blockY + threadIdx.y;
if ((ix < imageW) && (iy < imageH)) {
// Get the current pixel color
int pixel = imageW * iy + ix;
uchar4 pixelColor = dst[pixel];
int count = 0;
// Search for pixels out of tolerance surrounding the current pixel
if (ix > 0) {
count += CheckColors(pixelColor, dst[pixel - 1]);
}
if (ix + 1 < imageW) {
count += CheckColors(pixelColor, dst[pixel + 1]);
}
if (iy > 0) {
count += CheckColors(pixelColor, dst[pixel - imageW]);
}
if (iy + 1 < imageH) {
count += CheckColors(pixelColor, dst[pixel + imageW]);
}
if (count) {
// Calculate the location
const T xPos = (T)ix * scale + xOff;
const T yPos = (T)iy * scale + yOff;
// Calculate the Mandelbrot index for the current location
int m = CalcMandelbrot(xPos, yPos, xJP, yJP, crunch, isJ);
m = m > 0 ? crunch - m : 0;
// Convert the Mandelbrot index into a color
uchar4 color;
if (m) {
m += animationFrame;
color.x = m * colors.x;
color.y = m * colors.y;
color.z = m * colors.z;
}
else {
color.x = 0;
color.y = 0;
color.z = 0;
}
// Output the pixel
int frame1 = frame + 1;
int frame2 = frame1 / 2;
dst[pixel].x = (pixelColor.x * frame + color.x + frame2) / frame1;
dst[pixel].y = (pixelColor.y * frame + color.y + frame2) / frame1;
dst[pixel].z = (pixelColor.z * frame + color.z + frame2) / frame1;
}
}
}
} // Mandelbrot1
// The Mandelbrot secondary AA pass CUDA GPU thread function (double single
// version)
__global__ void MandelbrotDS1(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const float xOff0,
const float xOff1,
const float yOff0,
const float yOff1,
const float xJP,
const float yJP,
const float scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const int gridWidth,
const int numBlocks,
const bool isJ)
{
// loop until all blocks completed
for (unsigned int blockIndex = blockIdx.x; blockIndex < numBlocks; blockIndex += gridDim.x) {
unsigned int blockX = blockIndex % gridWidth;
unsigned int blockY = blockIndex / gridWidth;
// process this block
const int ix = blockDim.x * blockX + threadIdx.x;
const int iy = blockDim.y * blockY + threadIdx.y;
if ((ix < imageW) && (iy < imageH)) {
// Get the current pixel color
int pixel = imageW * iy + ix;
uchar4 pixelColor = dst[pixel];
int count = 0;
// Search for pixels out of tolerance surrounding the current pixel
if (ix > 0) {
count += CheckColors(pixelColor, dst[pixel - 1]);
}
if (ix + 1 < imageW) {
count += CheckColors(pixelColor, dst[pixel + 1]);
}
if (iy > 0) {
count += CheckColors(pixelColor, dst[pixel - imageW]);
}
if (iy + 1 < imageH) {
count += CheckColors(pixelColor, dst[pixel + imageW]);
}
if (count) {
// Calculate the location
float xPos0 = (float)ix * scale;
float xPos1 = 0.0f;
float yPos0 = (float)iy * scale;
float yPos1 = 0.0f;
dsadd(xPos0, xPos1, xPos0, xPos1, xOff0, xOff1);
dsadd(yPos0, yPos1, yPos0, yPos1, yOff0, yOff1);
// Calculate the Mandelbrot index for the current location
int m = CalcMandelbrotDS(xPos0, xPos1, yPos0, yPos1, xJP, yJP, crunch, isJ);
m = m > 0 ? crunch - m : 0;
// Convert the Mandelbrot index into a color
uchar4 color;
if (m) {
m += animationFrame;
color.x = m * colors.x;
color.y = m * colors.y;
color.z = m * colors.z;
}
else {
color.x = 0;
color.y = 0;
color.z = 0;
}
// Output the pixel
int frame1 = frame + 1;
int frame2 = frame1 / 2;
dst[pixel].x = (pixelColor.x * frame + color.x + frame2) / frame1;
dst[pixel].y = (pixelColor.y * frame + color.y + frame2) / frame1;
dst[pixel].z = (pixelColor.z * frame + color.z + frame2) / frame1;
}
}
}
} // MandelbrotDS1
// The host CPU Mandelbrot thread spawner
void RunMandelbrot0(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const double xOff,
const double yOff,
const double xjp,
const double yjp,
const double scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const int mode,
const int numSMs,
const bool isJ,
int version)
{
dim3 threads(BLOCKDIM_X, BLOCKDIM_Y);
dim3 grid(iDivUp(imageW, BLOCKDIM_X), iDivUp(imageH, BLOCKDIM_Y));
int numWorkerBlocks = numSMs;
switch (mode) {
default:
case 0:
Mandelbrot0<float><<<numWorkerBlocks, threads>>>(dst,
imageW,
imageH,
crunch,
(float)xOff,
(float)yOff,
(float)xjp,
(float)yjp,
(float)scale,
colors,
frame,
animationFrame,
grid.x,
grid.x * grid.y,
isJ);
break;
case 1:
float x0, x1, y0, y1;
dsdeq(x0, x1, xOff);
dsdeq(y0, y1, yOff);
MandelbrotDS0<<<numWorkerBlocks, threads>>>(dst,
imageW,
imageH,
crunch,
x0,
x1,
y0,
y1,
(float)xjp,
(float)yjp,
(float)scale,
colors,
frame,
animationFrame,
grid.x,
grid.x * grid.y,
isJ);
break;
case 2:
Mandelbrot0<double><<<numWorkerBlocks, threads>>>(dst,
imageW,
imageH,
crunch,
xOff,
yOff,
xjp,
yjp,
scale,
colors,
frame,
animationFrame,
grid.x,
grid.x * grid.y,
isJ);
break;
}
getLastCudaError("Mandelbrot0 kernel execution failed.\n");
} // RunMandelbrot0
// The host CPU Mandelbrot thread spawner
void RunMandelbrot1(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const double xOff,
const double yOff,
const double xjp,
const double yjp,
const double scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const int mode,
const int numSMs,
const bool isJ,
int version)
{
dim3 threads(BLOCKDIM_X, BLOCKDIM_Y);
dim3 grid(iDivUp(imageW, BLOCKDIM_X), iDivUp(imageH, BLOCKDIM_Y));
int numWorkerBlocks = numSMs;
switch (mode) {
default:
case 0:
Mandelbrot1<float><<<numWorkerBlocks, threads>>>(dst,
imageW,
imageH,
crunch,
(float)xOff,
(float)yOff,
(float)xjp,
(float)yjp,
(float)scale,
colors,
frame,
animationFrame,
grid.x,
grid.x * grid.y,
isJ);
break;
case 1:
float x0, x1, y0, y1;
dsdeq(x0, x1, xOff);
dsdeq(y0, y1, yOff);
MandelbrotDS1<<<numWorkerBlocks, threads>>>(dst,
imageW,
imageH,
crunch,
x0,
x1,
y0,
y1,
(float)xjp,
(float)yjp,
(float)scale,
colors,
frame,
animationFrame,
grid.x,
grid.x * grid.y,
isJ);
break;
case 2:
Mandelbrot1<double><<<numWorkerBlocks, threads>>>(dst,
imageW,
imageH,
crunch,
xOff,
yOff,
xjp,
yjp,
scale,
colors,
frame,
animationFrame,
grid.x,
grid.x * grid.y,
isJ);
break;
}
getLastCudaError("Mandelbrot1 kernel execution failed.\n");
} // RunMandelbrot1

View File

@@ -0,0 +1,342 @@
/* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of NVIDIA CORPORATION nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Mandelbrot_gold.h"
#define ABS(n) ((n) < 0 ? -(n) : (n))
/* dfloat class declaration */
class dfloat
{
private:
float val[2];
public:
dfloat() { val[0] = val[1] = 0; }
dfloat(float a, float b)
{
val[0] = a;
val[1] = b;
}
dfloat(double b);
inline float operator[](unsigned idx) const { return val[idx]; }
};
inline dfloat operator+(const dfloat &dsa, const dfloat &dsb);
inline dfloat operator-(const dfloat &dsa, const dfloat &dsb);
inline dfloat operator*(const dfloat &dsa, const dfloat &dsb);
inline int operator<(const dfloat &a, float b) { return a[0] < b; }
// The core Mandelbrot calculation function template
template <class T>
inline int
CalcMandelbrot(const T xPos, const T yPos, const T xJParam, const T yJParam, const int crunch, const bool isJulia)
{
T x, y, xx, yy, xC, yC;
int i = crunch;
if (isJulia) {
xC = xJParam;
yC = yJParam;
y = yPos;
x = xPos;
yy = y * y;
xx = x * x;
}
else {
xC = xPos;
yC = yPos;
x = y = 0;
xx = yy = 0;
}
while (--i && (xx + yy < 4.0f)) {
y = x * y + x * y + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
}
return i;
} // CalcMandelbrot
inline void updatePixel(uchar4 &dst, const uchar4 &color, int frame)
{
int frame1 = frame + 1;
int frame2 = frame1 / 2;
dst.x = (dst.x * frame + color.x + frame2) / frame1;
dst.y = (dst.y * frame + color.y + frame2) / frame1;
dst.z = (dst.z * frame + color.z + frame2) / frame1;
}
inline void setColor(uchar4 &dst, const uchar4 &colors, int &m, const int animationFrame)
{
if (m == 0) {
dst.x = 0;
dst.y = 0;
dst.z = 0;
return;
}
m += animationFrame;
dst.x = m * colors.x;
dst.y = m * colors.y;
dst.z = m * colors.z;
}
template <class T, class T_>
void runMandelbrotGold0(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const T xOff,
const T yOff,
const T xJParam,
const T yJParam,
const T scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const bool isJulia)
{
for (int iy = 0; iy < imageH; iy++)
for (int ix = 0; ix < imageW; ix++) {
// Calculate the location
const T_ xPos = (T)ix * scale + xOff;
const T_ yPos = (T)iy * scale + yOff;
// Calculate the Mandelbrot index for the current location
int m = CalcMandelbrot<T_>(xPos, yPos, xJParam, yJParam, crunch, isJulia);
m = m > 0 ? crunch - m : 0;
// Convert the Mandelbrot index into a color
uchar4 color;
setColor(color, colors, m, animationFrame);
// Output the pixel
int pixel = imageW * iy + ix;
if (frame == 0) {
color.w = 0;
dst[pixel] = color;
}
else
updatePixel(dst[pixel], color, frame);
}
} // runMandelbrotGold0_
// Determine if two pixel colors are within tolerance
inline int CheckColors(const uchar4 &color0, const uchar4 &color1)
{
int x = color1.x - color0.x;
int y = color1.y - color0.y;
int z = color1.z - color0.z;
return (ABS(x) > 10) || (ABS(y) > 10) || (ABS(z) > 10);
} // CheckColors
template <class T, class T_>
void runMandelbrotGold1(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const T xOff,
const T yOff,
const T xJParam,
const T yJParam,
const T scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const bool isJulia)
{
for (int iy = 0; iy < imageH; iy++)
for (int ix = 0; ix < imageW; ix++) {
// Get the current pixel color
int pixel = imageW * iy + ix;
uchar4 pixelColor = dst[pixel];
int count = 0;
// Search for pixels out of tolerance surrounding the current pixel
if (ix > 0)
count += CheckColors(pixelColor, dst[pixel - 1]);
if (ix + 1 < imageW)
count += CheckColors(pixelColor, dst[pixel + 1]);
if (iy > 0)
count += CheckColors(pixelColor, dst[pixel - imageW]);
if (iy + 1 < imageH)
count += CheckColors(pixelColor, dst[pixel + imageW]);
if (count) {
// Calculate the location
const T_ xPos = (T)ix * scale + xOff;
const T_ yPos = (T)iy * scale + yOff;
// Calculate the Mandelbrot index for the current location
int m = CalcMandelbrot<T_>(xPos, yPos, xJParam, yJParam, crunch, isJulia);
m = m > 0 ? crunch - m : 0;
// Convert the Mandelbrot index into a color
uchar4 color;
setColor(color, colors, m, animationFrame);
// Output the pixel
updatePixel(dst[pixel], color, frame);
}
}
} // RunMandelbrotGold1_
/* Implementation of exported functions */
void RunMandelbrotGold1(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const float xOff,
const float yOff,
const float xJParam,
const float yJParam,
const float scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const bool isJulia)
{
runMandelbrotGold1<float, float>(
dst, imageW, imageH, crunch, xOff, yOff, xJParam, yJParam, scale, colors, frame, animationFrame, isJulia);
} // RunMandelbrotGold1
void RunMandelbrotDSGold1(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const double xOff,
const double yOff,
const double xJParam,
const double yJParam,
const double scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const bool isJulia)
{
runMandelbrotGold1<double, dfloat>(
dst, imageW, imageH, crunch, xOff, yOff, xJParam, yJParam, scale, colors, frame, animationFrame, isJulia);
} // RunMandelbrotDSGold1
void RunMandelbrotGold0(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const float xOff,
const float yOff,
const float xJParam,
const float yJParam,
const float scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const bool isJulia)
{
runMandelbrotGold0<float, float>(
dst, imageW, imageH, crunch, xOff, yOff, xJParam, yJParam, scale, colors, frame, animationFrame, isJulia);
} // RunMandelbrotGold0
void RunMandelbrotDSGold0(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const double xOff,
const double yOff,
const double xJParam,
const double yJParam,
const double scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const bool isJulia)
{
runMandelbrotGold0<double, dfloat>(
dst, imageW, imageH, crunch, xOff, yOff, xJParam, yJParam, scale, colors, frame, animationFrame, isJulia);
} // RunMandelbrotDSGold0
/*dfloat operations implementation */
/* Construct a DS number equal to a double precision floating point number b*/
dfloat::dfloat(double b)
{
val[0] = (float)b;
val[1] = (float)(b - val[0]);
}
inline dfloat operator+(const dfloat &dsa, const dfloat &dsb)
{
// Compute dsa + dsb using Knuth's trick.
float t1 = dsa[0] + dsb[0];
float e = t1 - dsa[0];
float t2 = ((dsb[0] - e) + (dsa[0] - (t1 - e))) + dsa[1] + dsb[1];
// The result is t1 + t2, after normalization.
e = t1 + t2;
return dfloat(e, t2 - (e - t1));
}
inline dfloat operator-(const dfloat &dsa, const dfloat &dsb)
{
// Compute dsa - dsb using Knuth's trick.
float t1 = dsa[0] - dsb[0];
float e = t1 - dsa[0];
float t2 = ((-dsb[0] - e) + (dsa[0] - (t1 - e))) + dsa[1] - dsb[1];
// The result is t1 + t2, after normalization.
e = t1 + t2;
return dfloat(e, t2 - (e - t1));
}
inline dfloat operator*(const dfloat &dsa, const dfloat &dsb)
{
// This splits dsa(1) and dsb(1) into high-order and low-order words.
float c11 = dsa[0] * dsb[0];
float c21 = dsa[0] * dsb[0] - c11;
// Compute dsa[0] * dsb[1] + dsa[1] * dsb[0] (only high-order word is needed).
float c2 = dsa[0] * dsb[1] + dsa[1] * dsb[0];
// Compute (c11, c21) + c2 using Knuth's trick, also adding low-order product.
float t1 = c11 + c2;
float e = t1 - c11;
float t2 = ((c2 - e) + (c11 - (t1 - e))) + c21 + dsa[1] * dsb[1];
// The result is t1 + t2, after normalization.
e = t1 + t2;
return dfloat(e, t2 - (e - t1));
}

View File

@@ -0,0 +1,86 @@
/* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of NVIDIA CORPORATION nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MANDELBROT_GOLD_h_
#define _MANDELBROT_GOLD_h_
#include <vector_types.h>
extern "C" void RunMandelbrotGold0(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const float xOff,
const float yOff,
const float xJParam,
const float yJParam,
const float scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const bool isJulia);
extern "C" void RunMandelbrotDSGold0(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const double xOff,
const double yOff,
const double xJParam,
const double yJParam,
const double scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const bool isJulia);
extern "C" void RunMandelbrotGold1(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const float xOff,
const float yOff,
const float xJParam,
const float yJParam,
const float scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const bool isJulia);
extern "C" void RunMandelbrotDSGold1(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const double xOff,
const double yOff,
const double xJParam,
const double yJParam,
const double scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const bool isJulia);
#endif

View File

@@ -0,0 +1,484 @@
/* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of NVIDIA CORPORATION nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include "Mandelbrot_kernel.h"
#include "helper_cuda.h"
// The dimensions of the thread block
#define BLOCKDIM_X 16
#define BLOCKDIM_Y 16
#define ABS(n) ((n) < 0 ? -(n) : (n))
// Double single functions based on DSFUN90 package:
// http://crd.lbl.gov/~dhbailey/mpdist/index.html
// This function sets the DS number A equal to the double precision floating
// point number B.
inline void dsdeq(float &a0, float &a1, double b)
{
a0 = (float)b;
a1 = (float)(b - a0);
} // dsdcp
// This function sets the DS number A equal to the single precision floating
// point number B.
__device__ inline void dsfeq(float &a0, float &a1, float b)
{
a0 = b;
a1 = 0.0f;
} // dsfeq
// This function computes c = a + b.
__device__ inline void dsadd(float &c0, float &c1, const float a0, const float a1, const float b0, const float b1)
{
// Compute dsa + dsb using Knuth's trick.
float t1 = a0 + b0;
float e = t1 - a0;
float t2 = ((b0 - e) + (a0 - (t1 - e))) + a1 + b1;
// The result is t1 + t2, after normalization.
c0 = e = t1 + t2;
c1 = t2 - (e - t1);
} // dsadd
// This function computes c = a - b.
__device__ inline void dssub(float &c0, float &c1, const float a0, const float a1, const float b0, const float b1)
{
// Compute dsa - dsb using Knuth's trick.
float t1 = a0 - b0;
float e = t1 - a0;
float t2 = ((-b0 - e) + (a0 - (t1 - e))) + a1 - b1;
// The result is t1 + t2, after normalization.
c0 = e = t1 + t2;
c1 = t2 - (e - t1);
} // dssub
#if 1
// This function multiplies DS numbers A and B to yield the DS product C.
__device__ inline void dsmul(float &c0, float &c1, const float a0, const float a1, const float b0, const float b1)
{
// This splits dsa(1) and dsb(1) into high-order and low-order words.
float cona = a0 * 8193.0f;
float conb = b0 * 8193.0f;
float sa1 = cona - (cona - a0);
float sb1 = conb - (conb - b0);
float sa2 = a0 - sa1;
float sb2 = b0 - sb1;
// Multilply a0 * b0 using Dekker's method.
float c11 = a0 * b0;
float c21 = (((sa1 * sb1 - c11) + sa1 * sb2) + sa2 * sb1) + sa2 * sb2;
// Compute a0 * b1 + a1 * b0 (only high-order word is needed).
float c2 = a0 * b1 + a1 * b0;
// Compute (c11, c21) + c2 using Knuth's trick, also adding low-order product.
float t1 = c11 + c2;
float e = t1 - c11;
float t2 = ((c2 - e) + (c11 - (t1 - e))) + c21 + a1 * b1;
// The result is t1 + t2, after normalization.
c0 = e = t1 + t2;
c1 = t2 - (e - t1);
} // dsmul
#else
// Modified double-single mul function by Norbert Juffa, NVIDIA
// uses __fmul_rn() and __fadd_rn() intrinsics which prevent FMAD merging
/* Based on: Guillaume Da Gra<72>a, David Defour. Implementation of Float-Float
* Operators on Graphics Hardware. RNC'7 pp. 23-32, 2006.
*/
// This function multiplies DS numbers A and B to yield the DS product C.
__device__ inline void dsmul(float &c0, float &c1, const float a0, const float a1, const float b0, const float b1)
{
// This splits dsa(1) and dsb(1) into high-order and low-order words.
float cona = a0 * 8193.0f;
float conb = b0 * 8193.0f;
float sa1 = cona - (cona - a0);
float sb1 = conb - (conb - b0);
float sa2 = a0 - sa1;
float sb2 = b0 - sb1;
// Multilply a0 * b0 using Dekker's method.
float c11 = __fmul_rn(a0, b0);
float c21 = (((sa1 * sb1 - c11) + sa1 * sb2) + sa2 * sb1) + sa2 * sb2;
// Compute a0 * b1 + a1 * b0 (only high-order word is needed).
float c2 = __fmul_rn(a0, b1) + __fmul_rn(a1, b0);
// Compute (c11, c21) + c2 using Knuth's trick, also adding low-order product.
float t1 = c11 + c2;
float e = t1 - c11;
float t2 = ((c2 - e) + (c11 - (t1 - e))) + c21 + __fmul_rn(a1, b1);
// The result is t1 + t2, after normalization.
c0 = e = t1 + t2;
c1 = t2 - (e - t1);
} // dsmul
#endif
// The core Mandelbrot CUDA GPU calculation function
#if 1
// Unrolled version
template <class T>
__device__ inline int
CalcMandelbrot(const T xPos, const T yPos, const T xJParam, const T yJParam, const int crunch, const bool isJulia)
{
T x, y, xx, yy;
int i = crunch;
T xC, yC;
if (isJulia) {
xC = xJParam;
yC = yJParam;
y = yPos;
x = xPos;
yy = y * y;
xx = x * x;
}
else {
xC = xPos;
yC = yPos;
y = 0;
x = 0;
yy = 0;
xx = 0;
}
do {
// Iteration 1
if (xx + yy > T(4.0))
return i - 1;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 2
if (xx + yy > T(4.0))
return i - 2;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 3
if (xx + yy > T(4.0))
return i - 3;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 4
if (xx + yy > T(4.0))
return i - 4;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 5
if (xx + yy > T(4.0))
return i - 5;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 6
if (xx + yy > T(4.0))
return i - 6;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 7
if (xx + yy > T(4.0))
return i - 7;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 8
if (xx + yy > T(4.0))
return i - 8;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 9
if (xx + yy > T(4.0))
return i - 9;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 10
if (xx + yy > T(4.0))
return i - 10;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 11
if (xx + yy > T(4.0))
return i - 11;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 12
if (xx + yy > T(4.0))
return i - 12;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 13
if (xx + yy > T(4.0))
return i - 13;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 14
if (xx + yy > T(4.0))
return i - 14;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 15
if (xx + yy > T(4.0))
return i - 15;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 16
if (xx + yy > T(4.0))
return i - 16;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 17
if (xx + yy > T(4.0))
return i - 17;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 18
if (xx + yy > T(4.0))
return i - 18;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 19
if (xx + yy > T(4.0))
return i - 19;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
// Iteration 20
i -= 20;
if ((i <= 0) || (xx + yy > T(4.0)))
return i;
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
} while (1);
} // CalcMandelbrot
#else
template <class T>
__device__ inline int
CalcMandelbrot(const T xPos, const T yPos, const T xJParam, const T yJParam, const int crunch, const isJulia)
{
T x, y, xx, yy, xC, yC;
if (isJulia) {
xC = xJParam;
yC = yJParam;
y = yPos;
x = xPos;
yy = y * y;
xx = x * x;
}
else {
xC = xPos;
yC = yPos;
y = 0;
x = 0;
yy = 0;
xx = 0;
}
int i = crunch;
while (--i && (xx + yy < T(4.0))) {
y = x * y * T(2.0) + yC;
x = xx - yy + xC;
yy = y * y;
xx = x * x;
}
return i; // i > 0 ? crunch - i : 0;
} // CalcMandelbrot
#endif
// The core Mandelbrot calculation function in double-single precision
__device__ inline int CalcMandelbrotDS(const float xPos0,
const float xPos1,
const float yPos0,
const float yPos1,
const float xJParam,
const float yJParam,
const int crunch,
const bool isJulia)
{
float xx0, xx1;
float yy0, yy1;
float sum0, sum1;
int i = crunch;
float x0, x1, y0, y1;
float xC0, xC1, yC0, yC1;
if (isJulia) {
xC0 = xJParam;
xC1 = 0;
yC0 = yJParam;
yC1 = 0;
y0 = yPos0; // y = yPos;
y1 = yPos1;
x0 = xPos0; // x = xPos;
x1 = xPos1;
dsmul(yy0, yy1, y0, y1, y0, y1); // yy = y * y;
dsmul(xx0, xx1, x0, x1, x0, x1); // xx = x * x;
}
else {
xC0 = xPos0;
xC1 = xPos1;
yC0 = yPos0;
yC1 = yPos1;
y0 = 0; // y = 0 ;
y1 = 0;
x0 = 0; // x = 0 ;
x1 = 0;
yy0 = 0; // yy = 0 ;
yy1 = 0;
xx0 = 0; // xx = 0 ;
xx1 = 0;
}
dsadd(sum0, sum1, xx0, xx1, yy0, yy1); // sum = xx + yy;
while (--i && (sum0 + sum1 < 4.0f)) {
dsmul(y0, y1, x0, x1, y0, y1); // y = x * y * 2.0f + yC; // yC is yPos for
// Mandelbrot and it is yJParam for Julia
dsadd(y0, y1, y0, y1, y0, y1);
dsadd(y0, y1, y0, y1, yC0, yC1);
dssub(x0, x1, xx0, xx1, yy0, yy1); // x = xx - yy + xC; // xC is xPos for
// Mandelbrot and it is xJParam for
// Julia
dsadd(x0, x1, x0, x1, xC0, xC1);
dsmul(yy0, yy1, y0, y1, y0, y1); // yy = y * y;
dsmul(xx0, xx1, x0, x1, x0, x1); // xx = x * x;
dsadd(sum0, sum1, xx0, xx1, yy0, yy1); // sum = xx + yy;
}
return i;
} // CalcMandelbrotDS
// Determine if two pixel colors are within tolerance
__device__ inline int CheckColors(const uchar4 &color0, const uchar4 &color1)
{
int x = color1.x - color0.x;
int y = color1.y - color0.y;
int z = color1.z - color0.z;
return (ABS(x) > 10) || (ABS(y) > 10) || (ABS(z) > 10);
} // CheckColors
// Increase the grid size by 1 if the image width or height does not divide
// evenly
// by the thread block dimensions
inline int iDivUp(int a, int b) { return ((a % b) != 0) ? (a / b + 1) : (a / b); } // iDivUp

View File

@@ -0,0 +1,66 @@
/* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of NVIDIA CORPORATION nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MANDELBROT_KERNEL_h_
#define _MANDELBROT_KERNEL_h_
#include <vector_types.h>
extern "C" void RunMandelbrot0(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const double xOff,
const double yOff,
const double xjp,
const double yjp,
const double scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const int mode,
const int numSMs,
const bool isJ,
int version = 13);
extern "C" void RunMandelbrot1(uchar4 *dst,
const int imageW,
const int imageH,
const int crunch,
const double xOff,
const double yOff,
const double xjp,
const double yjp,
const double scale,
const uchar4 colors,
const int frame,
const int animationFrame,
const int mode,
const int numSMs,
const bool isJ,
int version = 13);
#endif

View File

@@ -0,0 +1,36 @@
# Mandelbrot - Mandelbrot
## Description
This sample uses CUDA to compute and display the Mandelbrot or Julia sets interactively. It also illustrates the use of "double single" arithmetic to improve precision when zooming a long way into the pattern. This sample uses double precision. Thanks to Mark Granger of NewTek who submitted this code sample.!
## Key Concepts
Graphics Interop, Data Parallel Algorithms
## Supported SM Architectures
[SM 5.0 ](https://developer.nvidia.com/cuda-gpus) [SM 5.2 ](https://developer.nvidia.com/cuda-gpus) [SM 5.3 ](https://developer.nvidia.com/cuda-gpus) [SM 6.0 ](https://developer.nvidia.com/cuda-gpus) [SM 6.1 ](https://developer.nvidia.com/cuda-gpus) [SM 7.0 ](https://developer.nvidia.com/cuda-gpus) [SM 7.2 ](https://developer.nvidia.com/cuda-gpus) [SM 7.5 ](https://developer.nvidia.com/cuda-gpus) [SM 8.0 ](https://developer.nvidia.com/cuda-gpus) [SM 8.6 ](https://developer.nvidia.com/cuda-gpus) [SM 8.7 ](https://developer.nvidia.com/cuda-gpus) [SM 8.9 ](https://developer.nvidia.com/cuda-gpus) [SM 9.0 ](https://developer.nvidia.com/cuda-gpus)
## Supported OSes
Linux, Windows
## Supported CPU Architecture
x86_64, armv7l
## CUDA APIs involved
### [CUDA Runtime API](http://docs.nvidia.com/cuda/cuda-runtime-api/index.html)
cudaGLUnmapBufferObject, cudaGraphicsUnmapResources, cudaMemcpy, cudaFree, cudaGLMapBufferObject, cudaGraphicsResourceGetMappedPointer, cudaGraphicsMapResources, cudaGLUnregisterBufferObject, cudaDeviceSynchronize, cudaGLRegisterBufferObject, cudaGraphicsUnregisterResource, cudaMalloc, cudaGraphicsGLRegisterBuffer, cudaGetDeviceProperties
## Dependencies needed to build/run
[X11](../../../README.md#x11), [OpenGL](../../../README.md#opengl), [Freeglut](../../../README.md#freeglut), [GLEW](../../../README.md#glew)
## Prerequisites
Download and install the [CUDA Toolkit](https://developer.nvidia.com/cuda-downloads) for your corresponding platform.
Make sure the dependencies mentioned in [Dependencies]() section above are installed.
## References (for more details)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
-0.085760 0.007040 3.200000 -0.172400 -0.652693

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB