aad-assignment-1/aad_coin_miner_cuda.c

154 lines
3.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Arquiteturas de Alto Desempenho 2025/2026
//
// DETI Coin Miner - CUDA implementation with histograms
//
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include "aad_data_types.h"
#include "aad_utilities.h"
#include "aad_sha1_cpu.h"
#include "aad_cuda_utilities.h"
#include "aad_vault.h"
#define COINS_STORAGE_SIZE 1024u
#define MAX_HISTOGRAM_BINS 100
static volatile int keep_running = 1;
void signal_handler(int signum)
{
(void)signum;
keep_running = 0;
}
// Coin reconstruction from stored data
static void reconstruct_coin(u32_t *stored_data, u32_t coin[14])
{
// Simply copy the complete coin data from storage
for(int i = 0; i < 14; i++)
coin[i] = stored_data[i];
}
//
// Mine DETI coins using CUDA
//
static void mine_coins_cuda(u64_t max_attempts)
{
cuda_data_t cd;
u32_t *host_storage;
u64_t attempts = 0;
u32_t coins_found = 0;
u32_t kernel_runs = 0;
// Initialize CUDA
cd.device_number = 0;
cd.cubin_file_name = "coin_miner_cuda_kernel.cubin";
cd.kernel_name = "mine_deti_coins_kernel";
cd.data_size[0] = COINS_STORAGE_SIZE * sizeof(u32_t);
cd.data_size[1] = 0;
initialize_cuda(&cd);
host_storage = (u32_t *)cd.host_data[0];
// Kernel configuration
cd.block_dim_x = RECOMMENDED_CUDA_BLOCK_SIZE;
cd.grid_dim_x = 4096; // Large grid for maximum GPU utilization
u32_t n_threads = cd.grid_dim_x * cd.block_dim_x;
printf("Mining DETI coins using CUDA...\n");
printf("Grid: %u blocks × %u threads = %u total threads\n",
cd.grid_dim_x, cd.block_dim_x, n_threads);
printf("Kernel: %s\n", cd.kernel_name);
printf("Press Ctrl+C to stop\n\n");
u64_t base_nonce = 0;
u32_t attempts_per_thread = 1024 * 8; // Increased attempts per thread
time_measurement();
while(keep_running && (max_attempts == 0 || attempts < max_attempts))
{
// Initialize storage area
host_storage[0] = 1u; // First unused index
// Copy to device
host_to_device_copy(&cd, 0);
// Set kernel arguments
cd.n_kernel_arguments = 2;
cd.arg[0] = &cd.device_data[0];
cd.arg[1] = &base_nonce;
cd.arg[2] = &attempts_per_thread;
// Launch the CUDA kernel
launch_kernel(&cd);
// Copy results back
device_to_host_copy(&cd, 0);
// Process found coins
u32_t n_coins_this_kernel = 0;
u32_t n_stored = (host_storage[0] - 1) / 14;
if(n_stored > 0 && host_storage[0] < COINS_STORAGE_SIZE)
{
for(u32_t i = 0; i < n_stored; i++)
{
u32_t coin[14];
reconstruct_coin(&host_storage[1 + i * 14], coin);
coins_found++;
n_coins_this_kernel++;
printf("COIN FOUND! (kernel %u, coin %u in this kernel). Total coins:%u\n",
kernel_runs, n_coins_this_kernel, coins_found);
save_coin(coin);
}
}
// Update counters
kernel_runs++;
u64_t attempts_this_launch = (u64_t)n_threads * attempts_per_thread;
attempts += attempts_this_launch;
base_nonce += attempts_this_launch;
}
time_measurement();
double total_time = cpu_time_delta();
printf("\n=== Mining Statistics ===\n");
printf("Total attempts: %llu\n", (unsigned long long)attempts);
printf("Total time: %.2f seconds\n", total_time);
printf("Average rate: %.2f attempts/second\n", attempts / total_time);
printf("Coins found: %u\n", coins_found);
printf("Kernel launches: %u\n", kernel_runs);
// Save any remaining coins
save_coin(NULL);
terminate_cuda(&cd);
}
int main(int argc, char *argv[])
{
u64_t max_attempts = 0;
signal(SIGINT, signal_handler);
if(argc > 1)
max_attempts = strtoull(argv[1], NULL, 10);
mine_coins_cuda(max_attempts);
return 0;
}