// // Arquiteturas de Alto Desempenho 2025/2026 // // DETI Coin Miner - OpenCL implementation // #include #include #include #include #include #include #include "aad_data_types.h" #include "aad_utilities.h" #include "aad_sha1_cpu.h" #include "aad_ocl_utilities.h" #include "aad_vault.h" #define COINS_STORAGE_SIZE 1024u 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]) { for(int i = 0; i < 14; i++) coin[i] = stored_data[i]; } // Get current wall time in seconds static double get_wall_time(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (double)ts.tv_sec + (double)ts.tv_nsec * 1.0e-9; } // // Mine DETI coins using OpenCL // static void mine_coins_ocl(u64_t max_attempts, double max_time) { ocl_data_t od; u32_t *host_storage; u64_t attempts = 0; u32_t coins_found = 0; u32_t kernel_runs = 0; // Initialize OpenCL od.platform_number = 0; od.device_number = 0; od.kernel_file_name = "aad_coin_miner_ocl_kernel.cl"; od.kernel_name = "mine_deti_coins_kernel"; od.data_size[0] = COINS_STORAGE_SIZE * sizeof(u32_t); od.data_size[1] = 0; initialize_ocl(&od); host_storage = (u32_t *)od.host_data[0]; // Kernel configuration od.local_work_size = RECOMMENDED_OCL_WORK_GROUP_SIZE; od.global_work_size = 4096 * od.local_work_size; u32_t n_threads = od.global_work_size; printf("Mining DETI coins using OpenCL...\n"); printf("Device: %s\n", od.device_name); printf("Work groups: %zu × %zu = %u total work items\n", od.global_work_size / od.local_work_size, od.local_work_size, n_threads); printf("Kernel: %s\n", od.kernel_name); if(max_attempts > 0 && max_time > 0) printf("Will stop after %llu attempts OR %.2f seconds (whichever comes first)\n", (unsigned long long)max_attempts, max_time); else if(max_attempts > 0) printf("Will stop after %llu attempts\n", (unsigned long long)max_attempts); else if(max_time > 0) printf("Will stop after %.2f seconds\n", max_time); else printf("Running indefinitely until Ctrl+C...\n"); printf("Press Ctrl+C to stop\n\n"); u32_t param1 = (u32_t)time(NULL); u32_t param2 = 0x12345678u; double start_time = get_wall_time(); while(keep_running) { // Check stopping conditions if(max_attempts > 0 && attempts >= max_attempts) break; double elapsed = get_wall_time() - start_time; if(max_time > 0 && elapsed >= max_time) break; // Initialize storage area host_storage[0] = 1u; // Copy to device host_to_device_copy(&od, 0); // Set kernel arguments od.n_kernel_arguments = 3; set_kernel_arg(&od, 0, sizeof(cl_mem), &od.device_data[0]); set_kernel_arg(&od, 1, sizeof(u32_t), ¶m1); set_kernel_arg(&od, 2, sizeof(u32_t), ¶m2); // Launch the OpenCL kernel launch_kernel(&od); // Copy results back device_to_host_copy(&od, 0); // Process found coins 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); // Verify it's actually a valid coin u32_t hash[5]; sha1(coin, hash); if(hash[0] == 0xAAD20250u) { coins_found++; printf("COIN FOUND! (kernel %u)\n", kernel_runs); save_coin(coin); } } } // Update counters kernel_runs++; attempts += n_threads; // Update parameters for next iteration param1++; param2 = param2 ^ 0x9E3779B9u; // Print progress every 10 kernel launches if(kernel_runs % 10 == 0) { elapsed = get_wall_time() - start_time; double rate = attempts / elapsed; printf("Attempts: %llu, Rate: %.2f MH/s, Coins: %u, Kernels: %u, Elapsed: %.2fs\n", (unsigned long long)attempts, rate / 1e6, coins_found, kernel_runs, elapsed); } } double total_time = get_wall_time() - start_time; 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_ocl(&od); } void print_usage(const char *prog_name) { printf("Usage: %s [OPTIONS]\n", prog_name); printf("Options:\n"); printf(" -a Maximum number of attempts\n"); printf(" -t Maximum time in seconds\n"); printf(" -h Show this help message\n"); printf("\nExamples:\n"); printf(" %s -a 1000000000 # Run for 1B attempts\n", prog_name); printf(" %s -t 60 # Run for 60 seconds\n", prog_name); printf(" %s -a 1000000000 -t 60 # Stop at 1B attempts OR 60s (whichever first)\n", prog_name); printf(" %s # Run indefinitely until Ctrl+C\n", prog_name); } int main(int argc, char *argv[]) { u64_t max_attempts = 0; double max_time = 0; int opt; signal(SIGINT, signal_handler); // Parse command line options while((opt = getopt(argc, argv, "a:t:h")) != -1) { switch(opt) { case 'a': max_attempts = strtoull(optarg, NULL, 10); break; case 't': max_time = atof(optarg); break; case 'h': print_usage(argv[0]); return 0; default: print_usage(argv[0]); return 1; } } mine_coins_ocl(max_attempts, max_time); return 0; }