Пример #1
0
        private void StartSolvingByDevice(Device.AMD device)
        {
            if (isStopSolving)
            {
                return;
            }

            Job nextJob = null, tempJob = null;

            var cpuThreadCount = 0;
            var edgeCount      = new uint[1];

            int[] edgeBuffer = new int[maxCpuHandleEdgeCount * 2];

            var clearPattern = Marshal.AllocHGlobal(4);

            Marshal.Copy(new byte[4] {
                0, 0, 0, 0
            }, 0, clearPattern, 4);

            var maxLogLevel = (Level)Math.Max((int)MinimumLogLevel, (int)MinimumFileLogLevel);
            var timer       = (maxLogLevel == Level.Verbose) ? new Stopwatch() : null;

            try
            {
                device.KernelSeedA.SetKernelArgument(0, device.BufferNonce);
                device.KernelSeedA.SetKernelArgument(1, device.BufferB);
                device.KernelSeedA.SetKernelArgument(2, device.BufferA1);
                device.KernelSeedA.SetKernelArgument(3, device.BufferI1);

                device.KernelSeedB1.SetKernelArgument(0, device.BufferA1);
                device.KernelSeedB1.SetKernelArgument(1, device.BufferA1);
                device.KernelSeedB1.SetKernelArgument(2, device.BufferA2);
                device.KernelSeedB1.SetKernelArgument(3, device.BufferI1);
                device.KernelSeedB1.SetKernelArgument(4, device.BufferI2);
                device.KernelSeedB1.SetKernelArgumentGeneric(5, (uint)32);

                device.KernelSeedB2.SetKernelArgument(0, device.BufferB);
                device.KernelSeedB2.SetKernelArgument(1, device.BufferA1);
                device.KernelSeedB2.SetKernelArgument(2, device.BufferA2);
                device.KernelSeedB2.SetKernelArgument(3, device.BufferI1);
                device.KernelSeedB2.SetKernelArgument(4, device.BufferI2);
                device.KernelSeedB2.SetKernelArgumentGeneric(5, (uint)0);

                device.KernelRound1.SetKernelArgument(0, device.BufferA1);
                device.KernelRound1.SetKernelArgument(1, device.BufferA2);
                device.KernelRound1.SetKernelArgument(2, device.BufferB);
                device.KernelRound1.SetKernelArgument(3, device.BufferI2);
                device.KernelRound1.SetKernelArgument(4, device.BufferI1);
                device.KernelRound1.SetKernelArgumentGeneric(5, (uint)Device.AMD.DUCK_SIZE_A * 1024);
                device.KernelRound1.SetKernelArgumentGeneric(6, (uint)Device.AMD.DUCK_SIZE_B * 1024);

                device.KernelRoundO.SetKernelArgument(0, device.BufferB);
                device.KernelRoundO.SetKernelArgument(1, device.BufferA1);
                device.KernelRoundO.SetKernelArgument(2, device.BufferI1);
                device.KernelRoundO.SetKernelArgument(3, device.BufferI2);

                device.KernelRoundNA.SetKernelArgument(0, device.BufferB);
                device.KernelRoundNA.SetKernelArgument(1, device.BufferA1);
                device.KernelRoundNA.SetKernelArgument(2, device.BufferI1);
                device.KernelRoundNA.SetKernelArgument(3, device.BufferI2);

                device.KernelRoundNB.SetKernelArgument(0, device.BufferA1);
                device.KernelRoundNB.SetKernelArgument(1, device.BufferB);
                device.KernelRoundNB.SetKernelArgument(2, device.BufferI2);
                device.KernelRoundNB.SetKernelArgument(3, device.BufferI1);

                device.KernelTail.SetKernelArgument(0, device.BufferB);
                device.KernelTail.SetKernelArgument(1, device.BufferA1);
                device.KernelTail.SetKernelArgument(2, device.BufferI1);
                device.KernelTail.SetKernelArgument(3, device.BufferI2);

                device.KernelRecovery.SetKernelArgument(0, device.BufferNonce);
                device.KernelRecovery.SetKernelArgument(1, device.BufferR);
                device.KernelRecovery.SetKernelArgument(2, device.BufferI2);
            }
            catch (Exception ex)
            {
                if (isStopSolving)
                {
                    return;
                }
                throw ex;
            }

            while (!isStopSolving)
            {
                try
                {
                    while (solutions.TryDequeue(out var solution))
                    {
                        device.CommandQueue.EnqueueWriteBuffer(device.BufferNonce, solution.Job.NonceHash, 32);

                        device.CommandQueue.EnqueueFillBuffer(device.BufferI2, 64 * 64 * 4, clearPattern);
                        device.CommandQueue.EnqueueWriteBuffer(device.BufferR, solution.GetLongEdges(), CycleFinder.CUCKOO_42);

                        device.CommandQueue.EnqueueNDRangeKernel(device.KernelRecovery, 1, 2048 * 256, 256, 0);

                        solution.nonces = device.CommandQueue.EnqueueReadBuffer <uint>(device.BufferI2, 42);

                        Task.Factory.StartNew(() =>
                        {
                            try
                            {
                                solution.nonces = solution.nonces.OrderBy(n => n).ToArray();

                                if (solution.CheckDifficulty(out ulong currentDiff, out ulong expectDiff))
                                {
                                    Log(Level.Debug, $"Solved difficulty of >={expectDiff} ({currentDiff})");
                                    solution.Job.OnJobSolved();

                                    Log(solution.Job.Origin.Category == FeeCategory.Miner
                                        ? Level.Info : Level.Debug,
                                        $"Device #{device.DeviceID} submitting solution...");

                                    solution.Job.Origin.SubmitSolution(new SubmitParams()
                                    {
                                        Height = solution.Job.Height,
                                        Nonce  = solution.Job.Nonce,
                                        JobID  = solution.Job.JobID,
                                        POW    = solution.nonces
                                    });
                                }
                                else
                                {
                                    Log(Level.Debug, $"Low difficulty solution of <{expectDiff} ({currentDiff})");
                                }
                            }
                            catch (Exception ex) { Log(ex); }
                        });
                    }

                    while (IsPause)
                    {
                        Task.Delay(500).Wait();
                    }

                    if (currentJob == null)
                    {
                        Task.Delay(500).Wait();
                        continue;
                    }
                    else if (tempJob == null || tempJob.JobID != currentJob.JobID || tempJob.Height != currentJob.Height)
                    {
                        nextJob = new Job(currentJob, device.DeviceID).NextNonce();
                    }

                    tempJob = nextJob;
                    var nextJobTask = Task.Factory.StartNew(() => tempJob.NextNonce(), TaskCreationOptions.LongRunning);

                    if (maxLogLevel == Level.Verbose)
                    {
                        timer.Restart();
                    }

                    device.CommandQueue.EnqueueWriteBuffer(device.BufferNonce, tempJob.NonceHash, 32);

                    device.CommandQueue.EnqueueFillBuffer(device.BufferI2, 64 * 64 * 4, clearPattern);
                    device.CommandQueue.EnqueueFillBuffer(device.BufferI1, 64 * 64 * 4, clearPattern);

                    device.CommandQueue.EnqueueNDRangeKernel(device.KernelSeedA, 1, 2048 * 128, 128, 0);

                    device.CommandQueue.EnqueueNDRangeKernel(device.KernelSeedB1, 1, 1024 * 128, 128, 0);
                    device.CommandQueue.EnqueueNDRangeKernel(device.KernelSeedB2, 1, 1024 * 128, 128, 0);

                    device.CommandQueue.EnqueueFillBuffer(device.BufferI1, 64 * 64 * 4, clearPattern);
                    device.CommandQueue.EnqueueNDRangeKernel(device.KernelRound1, 1, 4096 * 1024, 1024, 0);

                    device.CommandQueue.EnqueueFillBuffer(device.BufferI2, 64 * 64 * 4, clearPattern);
                    device.CommandQueue.EnqueueNDRangeKernel(device.KernelRoundO, 1, 4096 * 1024, 1024, 0);

                    device.CommandQueue.EnqueueFillBuffer(device.BufferI1, 64 * 64 * 4, clearPattern);
                    device.CommandQueue.EnqueueNDRangeKernel(device.KernelRoundNB, 1, 4096 * 1024, 1024, 0);

                    for (int r = 0; r < TrimRounds; r++)
                    {
                        device.CommandQueue.EnqueueFillBuffer(device.BufferI2, 64 * 64 * 4, clearPattern);
                        device.CommandQueue.EnqueueNDRangeKernel(device.KernelRoundNA, 1, 4096 * 1024, 1024, 0);

                        device.CommandQueue.EnqueueFillBuffer(device.BufferI1, 64 * 64 * 4, clearPattern);
                        device.CommandQueue.EnqueueNDRangeKernel(device.KernelRoundNB, 1, 4096 * 1024, 1024, 0);
                    }

                    device.CommandQueue.EnqueueFillBuffer(device.BufferI2, 64 * 64 * 4, clearPattern);
                    device.CommandQueue.EnqueueNDRangeKernel(device.KernelTail, 1, 4096 * 1024, 1024, 0);

                    device.CommandQueue.EnqueueReadBuffer(device.BufferI2, 1, ref edgeCount);

                    if (maxLogLevel == Level.Verbose)
                    {
                        Log(Level.Verbose, $"Device #{device.DeviceID} Job #{tempJob.JobID}: " +
                            $"Trimmed to {edgeCount[0]} edges in {timer.ElapsedMilliseconds}ms");
                    }

                    tempJob.EndSolveOn = DateTime.Now;

                    if (edgeCount[0] < maxCpuHandleEdgeCount)
                    {
                        device.CommandQueue.EnqueueReadBuffer(device.BufferA1, (int)edgeCount[0] * 2, ref edgeBuffer);

                        var handleJob      = tempJob;
                        var tempEdgeCount  = (int)edgeCount[0];
                        var tempEdgeBuffer = edgeBuffer.ToArray();

                        Task.Factory.StartNew(() =>
                        {
                            var uintEdgeBuffer = new uint[tempEdgeCount * sizeof(ulong) / sizeof(uint)];
                            Buffer.BlockCopy(tempEdgeBuffer, 0, uintEdgeBuffer, 0, tempEdgeCount * sizeof(uint) * 2);
                            tempEdgeBuffer = null;

                            var cf = CycleFinder.GetInstance();
                            cf.SetJob(handleJob);
                            cf.SetEdges(uintEdgeBuffer, tempEdgeCount);
                            try
                            {
                                if (cpuThreadCount++ < Math.Max(3, Environment.ProcessorCount))
                                {
                                    cf.FindSolutions(solutions);
                                }
                                else
                                {
                                    Log(Level.Warn, "CPU overloaded!");
                                }
                            }
                            finally
                            {
                                cpuThreadCount--;
                                CycleFinder.ReturnInstance(cf);
                            }
                        }, TaskCreationOptions.LongRunning);
                    }

                    AddToJobHistory(tempJob);
                    nextJob = nextJobTask.Result;
                }
                catch (Exception ex)
                {
                    Log(ex);
                    FreeDevice(device);
                    IsAnySolverCrashed = true;
                    break;
                }
            }
            Marshal.FreeHGlobal(clearPattern);
        }
Пример #2
0
        private void StartSolvingByDevice(Device.CUDA device)
        {
            if (isStopSolving)
            {
                return;
            }

            Job      nextJob = null, tempJob = null;
            Solution foundSolution = null;

            var cpuThreadCount = 0;
            var edgeCount      = new uint[2];
            var edgeBuffer     = new ulong[maxCpuHandleEdgeCount];

            var maxLogLevel = (Level)Math.Max((int)MinimumLogLevel, (int)MinimumFileLogLevel);
            var timer       = (maxLogLevel == Level.Verbose) ? new Stopwatch() : null;

            device.Context.SetCurrent();

            while (!isStopSolving)
            {
                try
                {
                    if (solutions.TryDequeue(out Solution solution))
                    {
                        foundSolution = solution;

                        device.IndexesB_device.MemsetAsync(0, device.Stream2.Stream);

                        device.MeanRecover.SetConstantVariable <byte>("nonce", foundSolution.Job.NonceHash);

                        device.MeanRecover.SetConstantVariable <ulong>("recovery", foundSolution.GetUlongEdges());

                        device.MeanRecover.RunAsync(device.Stream2.Stream,
                                                    device.IndexesB_device.DevicePointer);
                    }

                    while (IsPause)
                    {
                        Task.Delay(500).Wait();
                    }

                    if (currentJob == null)
                    {
                        Task.Delay(500).Wait();
                        continue;
                    }
                    else if (tempJob == null || tempJob.JobID != currentJob.JobID || tempJob.Height != currentJob.Height)
                    {
                        nextJob = new Job(currentJob, device.DeviceID).NextNonce();
                    }

                    tempJob = nextJob;

                    var nextJobTask = Task.Factory.StartNew(() => tempJob.NextNonce(), TaskCreationOptions.LongRunning);

                    if (maxLogLevel == Level.Verbose)
                    {
                        timer.Restart();
                    }

                    device.IndexesA_device.MemsetAsync(0, device.Stream1.Stream);
                    device.IndexesC_device.MemsetAsync(0, device.Stream2.Stream);

                    device.MeanSeedA.SetConstantVariable <byte>("nonce", tempJob.NonceHash);

                    device.MeanSeedA.RunAsync(device.Stream1.Stream,
                                              device.BufferMid_device.DevicePointer,
                                              device.IndexesA_device.DevicePointer);

                    if (foundSolution != null)
                    {
                        device.Stream2.Synchronize();

                        device.IndexesB_device.CopyToHost(foundSolution.nonces, 0, 0, CycleFinder.CUCKOO_42 * sizeof(uint));

                        var recoverSolution = foundSolution;
                        foundSolution = null;

                        Task.Factory.StartNew(() =>
                        {
                            try
                            {
                                recoverSolution.nonces = recoverSolution.nonces.OrderBy(n => n).ToArray();

                                if (recoverSolution.CheckDifficulty(out ulong currentDiff, out ulong expectDiff))
                                {
                                    Log(Level.Debug, $"Solved difficulty of >={expectDiff} ({currentDiff})");
                                    recoverSolution.Job.OnJobSolved();

                                    Log(recoverSolution.Job.Origin.Category == FeeCategory.Miner
                                        ? Level.Info : Level.Debug,
                                        $"Device #{device.DeviceID} submitting solution...");

                                    recoverSolution.Job.Origin.SubmitSolution(new SubmitParams()
                                    {
                                        Height = recoverSolution.Job.Height,
                                        Nonce  = recoverSolution.Job.Nonce,
                                        JobID  = recoverSolution.Job.JobID,
                                        POW    = recoverSolution.nonces
                                    });
                                }
                                else
                                {
                                    Log(Level.Debug, $"Low difficulty solution of <{expectDiff} ({currentDiff})");
                                }
                            }
                            catch (Exception ex) { Log(ex); }
                        });
                    }

                    device.IndexesB_device.MemsetAsync(0, device.Stream1.Stream);

                    device.Stream2.Synchronize();
                    device.Stream1.Synchronize();

                    for (var i = 0; i < 4; i++)
                    {
                        device.MeanSeedB_4.RunAsync(((i % 2) == 0) ? device.Stream1.Stream : device.Stream2.Stream,
                                                    device.BufferMid_device.DevicePointer,
                                                    device.Buffer_device.DevicePointer + (Device.CUDA.BUFFER_SIZE_A * 8 / 4 * i),
                                                    device.IndexesA_device.DevicePointer,
                                                    device.IndexesB_device.DevicePointer,
                                                    i * 16);
                    }

                    device.Stream1.Synchronize();
                    device.Stream2.Synchronize();

                    device.MeanRound_2.RunAsync(device.Stream1.Stream,
                                                device.Buffer_device.DevicePointer + ((Device.CUDA.BUFFER_SIZE_A * 8) / 4) * 2,
                                                device.BufferB_device.DevicePointer,
                                                device.IndexesB_device.DevicePointer + (2048 * 4),
                                                device.IndexesC_device.DevicePointer + (4096 * 4),
                                                Device.CUDA.DUCK_EDGES_A,
                                                Device.CUDA.DUCK_EDGES_B / 2);

                    device.MeanRound_2.RunAsync(device.Stream2.Stream,
                                                device.Buffer_device.DevicePointer,
                                                device.BufferB_device.DevicePointer - (Device.CUDA.BUFFER_SIZE_B * 8),
                                                device.IndexesB_device.DevicePointer,
                                                device.IndexesC_device.DevicePointer,
                                                Device.CUDA.DUCK_EDGES_A,
                                                Device.CUDA.DUCK_EDGES_B / 2);

                    device.Stream1.Synchronize();
                    device.Stream2.Synchronize();

                    device.IndexesA_device.MemsetAsync(0, device.Stream2.Stream);
                    device.IndexesB_device.MemsetAsync(0, device.Stream2.Stream);

                    device.MeanRoundJoin.RunAsync(device.Stream1.Stream,
                                                  device.BufferB_device.DevicePointer - (Device.CUDA.BUFFER_SIZE_B * 8),
                                                  device.BufferB_device.DevicePointer,
                                                  device.Buffer_device.DevicePointer,
                                                  device.IndexesC_device.DevicePointer,
                                                  device.IndexesX_device.DevicePointer,
                                                  Device.CUDA.DUCK_EDGES_B / 2,
                                                  Device.CUDA.DUCK_EDGES_B / 2);

                    device.MeanRound.RunAsync(device.Stream1.Stream,
                                              device.Buffer_device.DevicePointer,
                                              device.BufferB_device.DevicePointer,
                                              device.IndexesX_device.DevicePointer,
                                              device.IndexesY_device.DevicePointer,
                                              Device.CUDA.DUCK_EDGES_B / 2,
                                              Device.CUDA.DUCK_EDGES_B / 2);

                    device.MeanRound.RunAsync(device.Stream1.Stream,
                                              device.BufferB_device.DevicePointer,
                                              device.Buffer_device.DevicePointer,
                                              device.IndexesY_device.DevicePointer,
                                              device.IndexesZ_device.DevicePointer,
                                              Device.CUDA.DUCK_EDGES_B / 2,
                                              Device.CUDA.DUCK_EDGES_B / 2);

                    device.Stream2.Synchronize();

                    device.MeanRound.RunAsync(device.Stream1.Stream,
                                              device.Buffer_device.DevicePointer,
                                              device.BufferB_device.DevicePointer,
                                              device.IndexesZ_device.DevicePointer,
                                              device.Indexes_device[0, 0].DevicePointer,
                                              Device.CUDA.DUCK_EDGES_B / 2,
                                              Device.CUDA.DUCK_EDGES_B / 4);

                    device.Stream1.Synchronize();

                    device.IndexesX_device.MemsetAsync(0, device.Stream2.Stream);
                    device.IndexesY_device.MemsetAsync(0, device.Stream2.Stream);
                    device.IndexesZ_device.MemsetAsync(0, device.Stream2.Stream);

                    for (var i = 0; i < TrimRounds; i++)
                    {
                        device.MeanRound.RunAsync(device.Stream1.Stream,
                                                  device.BufferB_device.DevicePointer,
                                                  device.Buffer_device.DevicePointer,
                                                  device.Indexes_device[i, 0].DevicePointer,
                                                  device.Indexes_device[i, 1].DevicePointer,
                                                  Device.CUDA.DUCK_EDGES_B / 4,
                                                  Device.CUDA.DUCK_EDGES_B / 4);

                        device.MeanRound.RunAsync(device.Stream1.Stream,
                                                  device.Buffer_device.DevicePointer,
                                                  device.BufferB_device.DevicePointer,
                                                  device.Indexes_device[i, 1].DevicePointer,
                                                  device.Indexes_device[i + 1, 0].DevicePointer,
                                                  Device.CUDA.DUCK_EDGES_B / 4,
                                                  Device.CUDA.DUCK_EDGES_B / 4);
                    }

                    device.MeanTail.RunAsync(device.Stream1.Stream,
                                             device.BufferB_device.DevicePointer,
                                             device.Buffer_device.DevicePointer,
                                             device.Indexes_device[TrimRounds, 0].DevicePointer,
                                             device.Indexes_device[TrimRounds, 1].DevicePointer);

                    device.Stream1.Synchronize();

                    device.Indexes_device[TrimRounds, 1].CopyToHost(edgeCount, 0, 0, 8);

                    foreach (var index in device.Indexes_device)
                    {
                        index.MemsetAsync(0, device.Stream2.Stream);
                    }

                    if (maxLogLevel == Level.Verbose)
                    {
                        Log(Level.Verbose, $"Device #{device.DeviceID} Job #{tempJob.JobID}: " +
                            $"Trimmed to {edgeCount[0]} edges in {timer.ElapsedMilliseconds}ms");
                    }

                    tempJob.EndSolveOn = DateTime.Now;

                    if (edgeCount[0] < maxCpuHandleEdgeCount)
                    {
                        device.Buffer_device.CopyToHost(edgeBuffer, 0, 0, edgeCount[0] * 8);

                        var handleJob      = tempJob;
                        var tempEdgeCount  = (int)edgeCount[0];
                        var tempEdgeBuffer = edgeBuffer.ToArray();

                        Task.Factory.StartNew(() =>
                        {
                            var uintEdgeBuffer = new uint[tempEdgeCount * sizeof(ulong) / sizeof(uint)];
                            Buffer.BlockCopy(tempEdgeBuffer, 0, uintEdgeBuffer, 0, tempEdgeCount * sizeof(ulong));
                            tempEdgeBuffer = null;

                            var cf = CycleFinder.GetInstance();
                            cf.SetJob(handleJob);
                            cf.SetEdges(uintEdgeBuffer, tempEdgeCount);
                            try
                            {
                                if (cpuThreadCount++ < Math.Max(3, Environment.ProcessorCount))
                                {
                                    cf.FindSolutions(solutions);
                                }
                                else
                                {
                                    Log(Level.Warn, "CPU overloaded!");
                                }
                            }
                            finally
                            {
                                cpuThreadCount--;
                                CycleFinder.ReturnInstance(cf);
                            }
                        }, TaskCreationOptions.LongRunning);
                    }

                    AddToJobHistory(tempJob);
                    nextJob = nextJobTask.Result;
                }
                catch (Exception ex)
                {
                    Log(ex);
                    FreeDevice(device);
                    IsAnySolverCrashed = true;
                    break;
                }
            }
        }