I'm currently trying to implement the mandelbrot set in CUDA with SFML as a graphical frontend. I finished it in plain C++ and SFML to display the result and it worked well, I pretty much got the result I expected (which is an image of the mandelbrot set).
However once I ported the function that calculated how fast each point diverges to CUDA I got an exception. The code however is exactely the same except for the CUDA additions and I let it run on a single thread on a single block in the beginning.
This is the function that calculates the set.
__global__
void mandelbrot_set(int* m_set, double start_x, double end_x, double start_y, double end_y, int num_points, int max_iterations)
{
double spacing_x = abs(end_x - start_x) / ((double) num_points - 1.0);
double spacing_y = abs(end_y - start_y) / ((double) num_points - 1.0);
double current_x = start_x;
double current_y = start_y;
for (int i = 0; i < num_points; i++)
{
for (int j = 0; j < num_points; j++)
{
int index = i * num_points + j;
thrust::complex<double> c = thrust::complex<double>(current_x, current_y);
int iterations = max_iterations;
thrust::complex<double> z = thrust::complex<double>(0, 0);
for (int i = 0; i < max_iterations; i++)
{
z = z * z + c;
if (thrust::abs(z) > 4)
{
iterations = i;
break;
}
}
//int iterations = mandelbrot_point(c, max_iterations);
m_set[index] = iterations;
/*
If I remove the following line it works
(only it displays a black screen since the x-axis doesn't change anymore
*/
current_x = current_x + spacing_x;
}
current_x = start_x;
current_y = current_y + spacing_y;
}
}
And this is my main()
calling it.
int main()
{
constexpr int num_points = 1000;
constexpr int max_iterations = 120;
size_t size = num_points * num_points * sizeof(int);
//int blockSize = 256;
//int numBlocks = (num_points + blockSize - 1) / blockSize;
int* m_set;
cudaMallocManaged(&m_set, size);
mandelbrot_set<<<1, 1>>>(m_set, -2.25, 0.75, -1.5, 1.5, num_points, max_iterations);
cudaDeviceSynchronize();
constexpr int width = num_points;
constexpr int height = num_points;
sf::RenderWindow window(sf::VideoMode(width, height), "It works!");
sf::Uint8* image = set_to_image(m_set, num_points, 120);
sf::Texture texture;
if (!texture.create(width, height))
{
return -1;
}
texture.update(image);
sf::Sprite sprite;
sprite.setTexture(texture);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(sprite);
window.display();
}
cudaFree(m_set);
return 0;
}
__global__
to the mandelbrot_set functionint* m_set = new int[size];
to int* m_set; cudaMallocManaged(&m_set, size);
mandelbrot_set(m_set, -2.25, 0.75, -1.5, 1.5, num_points, max_iterations);
to mandelbrot_set<<<1, 1>>>(m_set, -2.25, 0.75, -1.5, 1.5, num_points, max_iterations);
cudaDeviceSynchronize();
User contributions licensed under CC BY-SA 3.0