separate wgsl file

This commit is contained in:
illuzen
2025-11-17 16:49:51 +08:00
parent 4578e076ce
commit 6fc2e9a209
2 changed files with 106 additions and 104 deletions
+2 -104
View File
@@ -20,110 +20,8 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
.request_device(&wgpu::DeviceDescriptor::default())
.await?;
// Create simplified WGSL mining shader (basic hash function for testing)
let shader_source = r#"
// Storage buffers
@group(0) @binding(0) var<storage, read_write> results: array<u32>;
@group(0) @binding(1) var<storage, read> header: array<u32, 8>; // 32 bytes
@group(0) @binding(2) var<storage, read> start_nonce: array<u32, 16>; // 64 bytes
@group(0) @binding(3) var<storage, read> difficulty_target: array<u32, 16>; // 64 bytes (U512 target)
// Simple hash function (placeholder for now)
fn simple_hash(input: array<u32, 24>) -> array<u32, 16> {
var result: array<u32, 16>;
// Very simple hash: XOR all input values and spread to output
var hash_val = 0u;
for (var i = 0u; i < 24u; i++) {
hash_val = hash_val ^ input[i];
hash_val = hash_val * 1103515245u + 12345u; // Simple LCG
}
// Fill output array with variations of hash
for (var i = 0u; i < 16u; i++) {
hash_val = hash_val * 1103515245u + 12345u;
result[i] = hash_val;
}
return result;
}
// Double hash
fn double_hash(input: array<u32, 24>) -> array<u32, 16> {
let first_hash = simple_hash(input);
// Convert back to input format for second hash
var second_input: array<u32, 24>;
for (var i = 0u; i < 16u; i++) {
second_input[i] = first_hash[i];
}
// Pad remaining with zeros
for (var i = 16u; i < 24u; i++) {
second_input[i] = 0u;
}
return simple_hash(second_input);
}
// Check if hash < target (U512 comparison)
fn is_below_target(hash: array<u32, 16>, difficulty_tgt: array<u32, 16>) -> bool {
// Compare from most significant to least significant
for (var i = 0u; i < 16u; i++) {
if (hash[15u - i] < difficulty_tgt[15u - i]) {
return true;
} else if (hash[15u - i] > difficulty_tgt[15u - i]) {
return false;
}
}
return false; // Equal, not below
}
@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
let thread_id = id.x;
// Prepare mining input: header (32 bytes) + nonce (64 bytes)
var mining_input: array<u32, 24>; // 96 bytes total
// Copy header (32 bytes = 8 u32s)
for (var i = 0u; i < 8u; i++) {
mining_input[i] = header[i];
}
// Calculate nonce for this thread
var nonce: array<u32, 16> = start_nonce;
// Add thread_id to the nonce (simplified increment)
var carry = thread_id;
for (var i = 0u; i < 16u && carry > 0u; i++) {
let old_val = nonce[i];
nonce[i] = old_val + carry;
// Check for overflow
if (nonce[i] < old_val) {
carry = 1u;
} else {
carry = 0u;
}
}
// Copy nonce (64 bytes = 16 u32s)
for (var i = 0u; i < 16u; i++) {
mining_input[8u + i] = nonce[i];
}
// Compute double Poseidon2 hash
let hash_result = double_hash(mining_input);
// Check if hash meets difficulty target
if (is_below_target(hash_result, difficulty_target)) {
// Found a valid nonce! Store it in results
results[0] = 1u; // Success flag
for (var i = 0u; i < 16u; i++) {
results[i + 1u] = nonce[i]; // Store winning nonce
}
for (var i = 0u; i < 16u; i++) {
results[i + 17u] = hash_result[i]; // Store winning hash
}
}
}
"#;
// Load WGSL shader from external file
let shader_source = include_str!("mining.wgsl");
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("Compute Shader"),
+104
View File
@@ -0,0 +1,104 @@
// Quantus Mining Shader - WGSL Compute Shader for GPU Mining
// Uses simplified hash function (to be replaced with Poseidon2)
// Storage buffers
@group(0) @binding(0) var<storage, read_write> results: array<u32>;
@group(0) @binding(1) var<storage, read> header: array<u32, 8>; // 32 bytes
@group(0) @binding(2) var<storage, read> start_nonce: array<u32, 16>; // 64 bytes
@group(0) @binding(3) var<storage, read> difficulty_target: array<u32, 16>; // 64 bytes (U512 target)
// Simple hash function (placeholder for Poseidon2)
fn simple_hash(input: array<u32, 24>) -> array<u32, 16> {
var result: array<u32, 16>;
// Very simple hash: XOR all input values and spread to output
var hash_val = 0u;
for (var i = 0u; i < 24u; i++) {
hash_val = hash_val ^ input[i];
hash_val = hash_val * 1103515245u + 12345u; // Simple LCG
}
// Fill output array with variations of hash
for (var i = 0u; i < 16u; i++) {
hash_val = hash_val * 1103515245u + 12345u;
result[i] = hash_val;
}
return result;
}
// Double hash (like Bitcoin's double SHA256)
fn double_hash(input: array<u32, 24>) -> array<u32, 16> {
let first_hash = simple_hash(input);
// Convert back to input format for second hash
var second_input: array<u32, 24>;
for (var i = 0u; i < 16u; i++) {
second_input[i] = first_hash[i];
}
// Pad remaining with zeros
for (var i = 16u; i < 24u; i++) {
second_input[i] = 0u;
}
return simple_hash(second_input);
}
// Check if hash < target (U512 comparison)
fn is_below_target(hash: array<u32, 16>, difficulty_tgt: array<u32, 16>) -> bool {
// Compare from most significant to least significant
for (var i = 0u; i < 16u; i++) {
if (hash[15u - i] < difficulty_tgt[15u - i]) {
return true;
} else if (hash[15u - i] > difficulty_tgt[15u - i]) {
return false;
}
}
return false; // Equal, not below
}
@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
let thread_id = id.x;
// Prepare mining input: header (32 bytes) + nonce (64 bytes)
var mining_input: array<u32, 24>; // 96 bytes total
// Copy header (32 bytes = 8 u32s)
for (var i = 0u; i < 8u; i++) {
mining_input[i] = header[i];
}
// Calculate nonce for this thread
var nonce: array<u32, 16> = start_nonce;
// Add thread_id to the nonce (simplified increment)
var carry = thread_id;
for (var i = 0u; i < 16u && carry > 0u; i++) {
let old_val = nonce[i];
nonce[i] = old_val + carry;
// Check for overflow
if (nonce[i] < old_val) {
carry = 1u;
} else {
carry = 0u;
}
}
// Copy nonce (64 bytes = 16 u32s)
for (var i = 0u; i < 16u; i++) {
mining_input[8u + i] = nonce[i];
}
// Compute double hash
let hash_result = double_hash(mining_input);
// Check if hash meets difficulty target
if (is_below_target(hash_result, difficulty_target)) {
// Found a valid nonce! Store it in results
results[0] = 1u; // Success flag
for (var i = 0u; i < 16u; i++) {
results[i + 1u] = nonce[i]; // Store winning nonce
}
for (var i = 0u; i < 16u; i++) {
results[i + 17u] = hash_result[i]; // Store winning hash
}
}
}