예제 #1
0
    static void Main(string[] args)
    {
        int[] r1 = new int[]
        { 8, 2, 3, 4 };
        int[] r2 = new int[]
        { 4, 3, 2, 5 };
        int[] r3      = new int[4];
        int   rowSize = r1.Length;
        // pick first platform
        ComputePlatform platform = ComputePlatform.Platforms[0];
        // create context with all gpu devices
        ComputeContext context = new ComputeContext(ComputeDeviceTypes.Gpu,
                                                    new ComputeContextPropertyList(platform), null, IntPtr.Zero);
        // create a command queue with first gpu found
        ComputeCommandQueue queue = new ComputeCommandQueue(context,
                                                            context.Devices[0], ComputeCommandQueueFlags.None);
        // load opencl source and
        // create program with opencl source
        ComputeProgram program = new ComputeProgram(context, CalculateKernel);

        // compile opencl source
        program.Build(null, null, null, IntPtr.Zero);
        // load chosen kernel from program
        ComputeKernel kernel = program.CreateKernel("Calc");
        // allocate a memory buffer with the message (the int array)
        ComputeBuffer <int> row1Buffer = new ComputeBuffer <int>(context,
                                                                 ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, r1);
        // allocate a memory buffer with the message (the int array)
        ComputeBuffer <int> row2Buffer = new ComputeBuffer <int>(context,
                                                                 ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, r2);
        // allocate a memory buffer with the message (the int array)
        ComputeBuffer <int> resultBuffer = new ComputeBuffer <int>(context,
                                                                   ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, new int[4]);

        kernel.SetMemoryArgument(0, row1Buffer);   // set the integer array
        kernel.SetMemoryArgument(1, row2Buffer);   // set the integer array
        kernel.SetValueArgument(2, rowSize);       // set the array size
        kernel.SetMemoryArgument(3, resultBuffer); // set the integer array
        // execute kernel
        queue.ExecuteTask(kernel, null);
        // wait for completion
        queue.Finish();
        GCHandle arrCHandle = GCHandle.Alloc(r3, GCHandleType.Pinned);

        queue.Read <int>(resultBuffer, true, 0, r3.Length, arrCHandle.AddrOfPinnedObject(), null);
        Console.WriteLine("display result from gpu buffer:");
        for (int i = 0; i < r3.Length; i++)
        {
            Console.WriteLine(r3[i]);
        }
        arrCHandle.Free();
        row1Buffer.Dispose();
        row2Buffer.Dispose();
        kernel.Dispose();
        program.Dispose();
        queue.Dispose();
        context.Dispose();
        Console.WriteLine("Finished");
        Console.ReadKey();
    }
예제 #2
0
        public void SetDevice(int deviceIndx)
        {
            if ((deviceIndx < 0) || (deviceIndx >= oclDevices.Count))
            {
                throw new IndexOutOfRangeException("Invalid OpenCL device index.");
            }

            if (oclContext != null)
            {
                oclContext.Dispose();
                oclContext = null;
            }

            if (oclCommandQueue != null)
            {
                oclCommandQueue.Dispose();
                oclCommandQueue = null;
            }

            if (oclKernel != null)
            {
                oclKernel.Dispose();
                oclKernel = null;
            }

            ComputeProgram oclProgram = null;

            try
            {
                oclContext = new ComputeContext(new ComputeDevice[] { oclDevices[deviceIndx] },
                                                new ComputeContextPropertyList(oclDevices[deviceIndx].Platform), null, IntPtr.Zero);

                oclCommandQueue = new ComputeCommandQueue(oclContext, oclDevices[deviceIndx],
                                                          ComputeCommandQueueFlags.None);

                oclProgram = new ComputeProgram(oclContext,
                                                Encoding.Default.GetString(Properties.Resources.Test));

                oclProgram.Build(new ComputeDevice[] { oclDevices[deviceIndx] }, "", null, IntPtr.Zero);

                oclKernel = oclProgram.CreateKernel("Test");
            }
            catch (BuildProgramFailureComputeException ex)
            {
                string buildLog = oclProgram.GetBuildLog(oclDevices[deviceIndx]);
                throw new Exception(buildLog, ex);
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                if (oclProgram != null)
                {
                    oclProgram.Dispose();
                    oclProgram = null;
                }
            }
        }
예제 #3
0
        public void Run(ComputeContext context, TextWriter log)
        {
            try
            {
                ComputeProgram program = new ComputeProgram(context, kernelSources);
                program.Build(null, null, null, IntPtr.Zero);
                log.WriteLine("Program successfully built.");
                ICollection <ComputeKernel> kernels = program.CreateAllKernels();
                log.WriteLine("Kernels successfully created.");

                // cleanup kernels
                foreach (ComputeKernel kernel in kernels)
                {
                    kernel.Dispose();
                }
                kernels.Clear();

                // cleanup program
                program.Dispose();
            }
            catch (Exception e)
            {
                log.WriteLine(e.ToString());
            }
        }
예제 #4
0
        protected ComputeProgram BuildProgram(string programName, long localWorkSize, string optionsAMD, string optionsNVIDIA, string optionsOthers)
        {
            ComputeProgram program;
            string         defultBinaryFilePath = @"BinaryKernels\" + ComputeDevice.Name + "_" + programName + "_" + localWorkSize + ".bin";
            string         savedBinaryFilePath  = (MainForm.SavedOpenCLBinaryKernelPathBase + @"\") + ComputeDevice.Name + "_" + programName + "_" + localWorkSize + ".bin";
            string         sourceFilePath       = @"Kernels\" + programName + ".cl";
            String         buildOptions         = (OpenCLDevice.GetVendor() == "AMD" ? optionsAMD : OpenCLDevice.GetVendor() == "NVIDIA" ? optionsNVIDIA : optionsOthers) + " -IKernels -DWORKSIZE=" + localWorkSize;

            try {
                if (!MainForm.UseDefaultOpenCLBinariesChecked)
                {
                    throw new Exception();
                }
                byte[] binary = System.IO.File.ReadAllBytes(defultBinaryFilePath);
                program = new ComputeProgram(Context, new List <byte[]>()
                {
                    binary
                }, new List <ComputeDevice>()
                {
                    ComputeDevice
                });
                MainForm.Logger("Loaded " + defultBinaryFilePath + " for Device #" + DeviceIndex + ".");
            } catch (Exception) {
                try {
                    if (!MainForm.ReuseCompiledBinariesChecked)
                    {
                        throw new Exception();
                    }
                    byte[] binary = System.IO.File.ReadAllBytes(savedBinaryFilePath);
                    program = new ComputeProgram(Context, new List <byte[]>()
                    {
                        binary
                    }, new List <ComputeDevice>()
                    {
                        ComputeDevice
                    });
                    MainForm.Logger("Loaded " + savedBinaryFilePath + " for Device #" + DeviceIndex + ".");
                } catch (Exception) {
                    String source = System.IO.File.ReadAllText(sourceFilePath);
                    program = new ComputeProgram(Context, source);
                    MainForm.Logger(@"Loaded " + sourceFilePath + " for Device #" + DeviceIndex + ".");
                }
            }
            try {
                program.Build(OpenCLDevice.DeviceList, buildOptions, null, IntPtr.Zero);
                if (MainForm.ReuseCompiledBinariesChecked)
                {
                    System.IO.File.WriteAllBytes(savedBinaryFilePath, program.Binaries[0]);
                }
            } catch (Exception) {
                MainForm.Logger(program.GetBuildLog(ComputeDevice));
                program.Dispose();
                throw;
            }
            MainForm.Logger("Built " + programName + " program for Device #" + DeviceIndex + ".");
            MainForm.Logger("Build options: " + buildOptions);

            return(program);
        }
예제 #5
0
        public void Dispose()
        {
            program.Dispose();
            context.Dispose();

            kernel.Dispose();

            commands.Dispose();
        }
예제 #6
0
        public void Dispose()
        {
            FWaveformBuffer.Dispose();

            commands.Dispose();
            kernel.Dispose();
            program.Dispose();
            FContext.Dispose();
            FDevice = null;
        }
예제 #7
0
 public void Dispose()
 {
     if (_kernels != null)
     {
         foreach (var kernel in _kernels)
         {
             kernel.Dispose();
         }
     }
     _program.Dispose();
 }
예제 #8
0
 static void TearDownCUDA()
 {
     context.Dispose();
     queue.Dispose();
     kernel.Dispose();
     messageBuffer.Dispose();
     if (gradientBuffer != null)
     {
         gradientBuffer.Dispose();
     }
     program.Dispose();
 }
예제 #9
0
 protected virtual void Dispose(bool disposing)
 {
     if (disposing)
     {
         clCommands.Dispose();
         clKernel.Dispose();
         clProgram.Dispose();
         clContext.Dispose();
         cbuf_Result.Dispose();
         cbuf_Rng.Dispose();
     }
 }
예제 #10
0
        private Tuple <TFP[], TFP[]> Compute(int imageWidth, int imageHeight, int unit, float originx, float originy, string funcCode, string funcdxCode, string funcdyCode)
        {
            int w  = imageWidth - 2;
            int h  = imageHeight - 2;
            int cx = imageWidth / 2;
            int cy = imageHeight / 2;

            int bufferSize = w * h;

            ComputeBuffer <TFP> points = new ComputeBuffer <TFP>(context, ComputeMemoryFlags.WriteOnly, bufferSize);

            string source = Encoding.ASCII.GetString(Properties.Resources.function_vis);

            source = source.Replace("{func}", funcCode);
            source = source.Replace("{dfuncdx}", funcdxCode);
            source = source.Replace("{dfuncdy}", funcdyCode);

            if (fpType == FPType.FP64AMD)
            {
                source = "#define AMDFP64\n" + source;
            }
            else if (fpType == FPType.FP64)
            {
                source = "#define FP64\n" + source;
            }

            ComputeProgram program = new ComputeProgram(context, source);

            try
            {
                program.Build(null, null, null, IntPtr.Zero);
            }
            catch (Exception)
            {
                var log = program.GetBuildLog(context.Devices[0]);
                Debugger.Break();
            }

            ComputeKernel kernelx = program.CreateKernel("ComputeX");
            ComputeKernel kernely = program.CreateKernel("ComputeY");

            TFP[] pointsArrayX = RunKernal(unit, w, h, cx, cy, originx, originy, bufferSize, points, kernelx);
            TFP[] pointsArrayY = RunKernal(unit, w, h, cx, cy, originx, originy, bufferSize, points, kernely);

            kernelx.Dispose();
            kernely.Dispose();
            program.Dispose();
            points.Dispose();

            return(Tuple.Create(pointsArrayX, pointsArrayY));
        }
예제 #11
0
        public void Run(ComputeContext context, TextWriter log)
        {
            this.log = log;

            try
            {
                program = new ComputeProgram(context, clSource);
                program.Build(null, null, notify, IntPtr.Zero);
            }
            catch (Exception e)
            {
                log.WriteLine(e.ToString());
            }

            // cleanup program
            program.Dispose();
        }
예제 #12
0
        public void DisposeComponents()
        {
            //RELEASE KERNELS
            kernel_block_prefix.Dispose();
            kernel_block_scan.Dispose();
            kernel_block_sort.Dispose();
            kernel_reorder.Dispose();
            k_reorder.Dispose();
            k_elementCount.Dispose();
            k_prefixSum.Dispose();
            k_ccArrayCreation.Dispose();
            k_dataInitialization.Dispose();

            //RELEASE PROGRAMS
            p_elementCount.Dispose();
            p_reorder.Dispose();
            p_radixSort.Dispose();
            p_prefixSum.Dispose();
            p_dataInitialization.Dispose();
            p_ccArrayCreation.Dispose();
        }
예제 #13
0
        void DestroyClBuffers()
        {
            if (clImage != null)
            {
                clImage.Dispose();
                clImage = null;
            }

            if (result != null)
            {
                result.Dispose();
                result = null;
            }
            if (cmap != null)
            {
                cmap.Dispose();
                cmap = null;
            }
            if (clCommands != null)
            {
                clCommands.Dispose();
                clCommands = null;
            }
            if (clKernel != null)
            {
                clKernel.Dispose();
                clKernel = null;
            }
            if (clProgram != null)
            {
                clProgram.Dispose();
                clProgram = null;
            }

            clDirty = true;
        }
예제 #14
0
        override unsafe protected void MinerThread()
        {
            ComputeProgram program = null;

            try {
                Random        r                = new Random();
                ComputeDevice computeDevice    = OpenCLDevice.GetComputeDevice();
                UInt32[]      ethashOutput     = new UInt32[256];
                byte[]        ethashHeaderhash = new byte[32];

                MarkAsAlive();

                MainForm.Logger("Miner thread for Device #" + DeviceIndex + " started.");

                program = BuildProgram("ethash_pascal", mEthashLocalWorkSizeArray[0], "-O1", "", "");

                MemoryUsage  = 256;
                MemoryUsage += 32;
                MemoryUsage += sPascalInputSize;
                MemoryUsage += sPascalOutputSize;
                MemoryUsage += sPascalMidstateSize;

                using (var searchKernel = program.CreateKernel("search"))
                    using (var DAGKernel = program.CreateKernel("GenerateDAG"))
                        using (var ethashOutputBuffer = new ComputeBuffer <UInt32>(Context, ComputeMemoryFlags.ReadWrite, 256))
                            using (var ethashHeaderBuffer = new ComputeBuffer <byte>(Context, ComputeMemoryFlags.ReadOnly, 32))
                                using (var pascalInputBuffer = new ComputeBuffer <byte>(Context, ComputeMemoryFlags.ReadOnly, sPascalInputSize))
                                    using (var pascalOutputBuffer = new ComputeBuffer <UInt32>(Context, ComputeMemoryFlags.ReadWrite, sPascalOutputSize))
                                        using (var pascalMidstateBuffer = new ComputeBuffer <byte>(Context, ComputeMemoryFlags.ReadOnly, sPascalMidstateSize))
                                            fixed(UInt32 *ethashOutputPtr = ethashOutput)
                                            fixed(byte *ethashHeaderhashPtr = ethashHeaderhash)
                                            fixed(byte *pascalMidstatePtr   = mPascalMidstate)
                                            fixed(byte *pascalInputPtr      = mPascalInput)
                                            fixed(UInt32 * pascalOutputPtr  = mPascalOutput)
                                            while (!Stopped)
                                            {
                                                ComputeBuffer <byte> ethashDAGBuffer = null;

                                                MarkAsAlive();

                                                try {
                                                    int  ethashEpoch   = -1;
                                                    long ethashDAGSize = 0;

                                                    searchKernel.SetMemoryArgument(7 + 0, pascalInputBuffer);
                                                    searchKernel.SetMemoryArgument(7 + 1, pascalOutputBuffer);
                                                    searchKernel.SetMemoryArgument(7 + 4, pascalMidstateBuffer);
                                                    searchKernel.SetValueArgument <UInt32>(7 + 5, mPascalRatio);

                                                    // Wait for the first job to arrive.
                                                    int elapsedTime = 0;
                                                    while ((PrimaryStratum == null || PrimaryStratum.GetJob() == null || SecondaryStratum == null || SecondaryStratum.GetJob() == null) && elapsedTime < Parameters.TimeoutForFirstJobInMilliseconds && !Stopped)
                                                    {
                                                        Thread.Sleep(100);
                                                        elapsedTime += 100;
                                                    }
                                                    if (PrimaryStratum == null || PrimaryStratum.GetJob() == null || SecondaryStratum == null || SecondaryStratum.GetJob() == null)
                                                    {
                                                        throw new TimeoutException("Stratum server failed to send a new job.");
                                                    }

                                                    System.Diagnostics.Stopwatch consoleUpdateStopwatch = new System.Diagnostics.Stopwatch();
                                                    EthashStratum.Work           ethashWork;
                                                    EthashStratum.Job            ethashJob;
                                                    PascalStratum.Work           pascalWork;
                                                    PascalStratum.Job            pascalJob;

                                                    while (!Stopped &&
                                                           (ethashWork = PrimaryStratum.GetWork()) != null && (ethashJob = ethashWork.GetJob()) != null &&
                                                           (pascalWork = SecondaryStratum.GetWork()) != null && (pascalJob = pascalWork.Job) != null)
                                                    {
                                                        MarkAsAlive();

                                                        String ethashPoolExtranonce      = PrimaryStratum.PoolExtranonce;
                                                        byte[] ethashExtranonceByteArray = Utilities.StringToByteArray(ethashPoolExtranonce);
                                                        byte   ethashLocalExtranonce     = (byte)ethashWork.LocalExtranonce;
                                                        UInt64 ethashStartNonce          = (UInt64)ethashLocalExtranonce << (8 * (7 - ethashExtranonceByteArray.Length));
                                                        for (int i = 0; i < ethashExtranonceByteArray.Length; ++i)
                                                        {
                                                            ethashStartNonce |= (UInt64)ethashExtranonceByteArray[i] << (8 * (7 - i));
                                                        }
                                                        ethashStartNonce += (ulong)r.Next(0, int.MaxValue) & (0xfffffffffffffffful >> (ethashExtranonceByteArray.Length * 8 + 8));
                                                        String ethashJobID      = ethashJob.ID;
                                                        String ethashSeedhash   = ethashJob.Seedhash;
                                                        double ethashDifficulty = PrimaryStratum.Difficulty;
                                                        Buffer.BlockCopy(Utilities.StringToByteArray(ethashWork.GetJob().Headerhash), 0, ethashHeaderhash, 0, 32);
                                                        Queue.Write <byte>(ethashHeaderBuffer, true, 0, 32, (IntPtr)ethashHeaderhashPtr, null);

                                                        Array.Copy(pascalWork.Blob, mPascalInput, sPascalInputSize);
                                                        CalculatePascalMidState();
                                                        Queue.Write <byte>(pascalMidstateBuffer, true, 0, sPascalMidstateSize, (IntPtr)pascalMidstatePtr, null);
                                                        UInt32 pascalStartNonce = (UInt32)(r.Next(0, int.MaxValue));
                                                        UInt64 PascalTarget     = (UInt64)((double)0xffff0000UL / SecondaryStratum.Difficulty);
                                                        searchKernel.SetValueArgument <UInt64>(7 + 3, PascalTarget);
                                                        Queue.Write <byte>(pascalInputBuffer, true, 0, sPascalInputSize, (IntPtr)pascalInputPtr, null);

                                                        if (ethashEpoch != ethashWork.GetJob().Epoch)
                                                        {
                                                            if (ethashDAGBuffer != null)
                                                            {
                                                                MemoryUsage -= ethashDAGBuffer.Size;
                                                                ethashDAGBuffer.Dispose();
                                                                ethashDAGBuffer = null;
                                                            }
                                                            ethashEpoch = ethashWork.GetJob().Epoch;
                                                            DAGCache cache = new DAGCache(ethashEpoch, ethashWork.GetJob().Seedhash);
                                                            ethashDAGSize = Utilities.GetDAGSize(ethashEpoch);

                                                            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                                                            sw.Start();
                                                            mEthashGlobalWorkSizeArray[0]  = ethashDAGSize / 64;
                                                            mEthashGlobalWorkSizeArray[0] /= 8;
                                                            if (mEthashGlobalWorkSizeArray[0] % mEthashLocalWorkSizeArray[0] > 0)
                                                            {
                                                                mEthashGlobalWorkSizeArray[0] += mEthashLocalWorkSizeArray[0] - mEthashGlobalWorkSizeArray[0] % mEthashLocalWorkSizeArray[0];
                                                            }

                                                            ComputeBuffer <byte> DAGCacheBuffer = new ComputeBuffer <byte>(Context, ComputeMemoryFlags.ReadOnly, cache.GetData().Length);
                                                            MemoryUsage += DAGCacheBuffer.Size;

                                                            fixed(byte *p = cache.GetData())
                                                            Queue.Write <byte>(DAGCacheBuffer, true, 0, cache.GetData().Length, (IntPtr)p, null);

                                                            ethashDAGBuffer = new ComputeBuffer <byte>(Context, ComputeMemoryFlags.ReadWrite, mEthashGlobalWorkSizeArray[0] * 8 * 64 /* ethashDAGSize */); // With this, we can remove a conditional statement in the DAG kernel.
                                                            MemoryUsage    += ethashDAGBuffer.Size;

                                                            DAGKernel.SetValueArgument <UInt32>(0, 0);
                                                            DAGKernel.SetMemoryArgument(1, DAGCacheBuffer);
                                                            DAGKernel.SetMemoryArgument(2, ethashDAGBuffer);
                                                            DAGKernel.SetValueArgument <UInt32>(3, (UInt32)cache.GetData().Length / 64);
                                                            DAGKernel.SetValueArgument <UInt32>(4, 0xffffffffu);

                                                            for (long start = 0; start < ethashDAGSize / 64; start += mEthashGlobalWorkSizeArray[0])
                                                            {
                                                                mEthashGlobalWorkOffsetArray[0] = start;
                                                                Queue.Execute(DAGKernel, mEthashGlobalWorkOffsetArray, mEthashGlobalWorkSizeArray, mEthashLocalWorkSizeArray, null);
                                                                Queue.Finish();
                                                                if (Stopped || PrimaryStratum.GetJob() == null || !PrimaryStratum.GetJob().ID.Equals(ethashJobID))
                                                                {
                                                                    break;
                                                                }
                                                            }
                                                            DAGCacheBuffer.Dispose();
                                                            MemoryUsage -= DAGCacheBuffer.Size;
                                                            if (Stopped || PrimaryStratum.GetJob() == null || !PrimaryStratum.GetJob().ID.Equals(ethashJobID))
                                                            {
                                                                break;
                                                            }
                                                            sw.Stop();
                                                            MainForm.Logger("Generated DAG for Epoch #" + ethashEpoch + " (" + (long)sw.Elapsed.TotalMilliseconds + "ms).");
                                                        }

                                                        consoleUpdateStopwatch.Start();

                                                        while (!Stopped && PrimaryStratum.GetJob().ID.Equals(ethashJobID) && PrimaryStratum.PoolExtranonce.Equals(ethashPoolExtranonce) && SecondaryStratum.GetJob().Equals(pascalJob))
                                                        {
                                                            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                                                            sw.Start();

                                                            MarkAsAlive();

                                                            // Get a new local extranonce if necessary.
                                                            if ((ethashStartNonce & (0xfffffffffffffffful >> (ethashExtranonceByteArray.Length * 8 + 8)) + (ulong)mEthashGlobalWorkSizeArray[0] * 3 / 4) >= ((ulong)0x1 << (64 - (ethashExtranonceByteArray.Length * 8 + 8))))
                                                            {
                                                                break;
                                                            }
                                                            if (0xffffffffu - pascalStartNonce < (UInt32)mEthashGlobalWorkSizeArray[0] * mPascalRatio)
                                                            {
                                                                break;
                                                            }

                                                            UInt64 target = (UInt64)((double)0xffff0000U / ethashDifficulty);
                                                            searchKernel.SetMemoryArgument(0, ethashOutputBuffer);                    // g_output
                                                            searchKernel.SetMemoryArgument(1, ethashHeaderBuffer);                    // g_header
                                                            searchKernel.SetMemoryArgument(2, ethashDAGBuffer);                       // _g_dag
                                                            searchKernel.SetValueArgument <UInt32>(3, (UInt32)(ethashDAGSize / 128)); // DAG_SIZE
                                                            searchKernel.SetValueArgument <UInt64>(4, ethashStartNonce);              // start_nonce
                                                            searchKernel.SetValueArgument <UInt64>(5, target);                        // target
                                                            searchKernel.SetValueArgument <UInt32>(6, 0xffffffffu);                   // isolate

                                                            searchKernel.SetValueArgument <UInt32>(7 + 2, pascalStartNonce);

                                                            ethashOutput[255] = 0; // ethashOutput[255] is used as an atomic counter.
                                                            Queue.Write <UInt32>(ethashOutputBuffer, true, 0, 256, (IntPtr)ethashOutputPtr, null);
                                                            mEthashGlobalWorkOffsetArray[0] = 0;
                                                            mPascalOutput[255] = 0; // mPascalOutput[255] is used as an atomic counter.
                                                            Queue.Write <UInt32>(pascalOutputBuffer, true, 0, sPascalOutputSize, (IntPtr)pascalOutputPtr, null);
                                                            Queue.Execute(searchKernel, mEthashGlobalWorkOffsetArray, mEthashGlobalWorkSizeArray, mEthashLocalWorkSizeArray, null);

                                                            Queue.Read <UInt32>(ethashOutputBuffer, true, 0, 256, (IntPtr)ethashOutputPtr, null);
                                                            if (PrimaryStratum.GetJob() != null && PrimaryStratum.GetJob().ID.Equals(ethashJobID))
                                                            {
                                                                for (int i = 0; i < ethashOutput[255]; ++i)
                                                                {
                                                                    PrimaryStratum.Submit(Device, ethashWork.GetJob(), ethashStartNonce + (UInt64)ethashOutput[i]);
                                                                }
                                                            }
                                                            ethashStartNonce += (UInt64)mEthashGlobalWorkSizeArray[0] * 3 / 4;

                                                            Queue.Read <UInt32>(pascalOutputBuffer, true, 0, sPascalOutputSize, (IntPtr)pascalOutputPtr, null);
                                                            if (SecondaryStratum.GetJob() != null && SecondaryStratum.GetJob().Equals(pascalJob))
                                                            {
                                                                for (int i = 0; i < mPascalOutput[255]; ++i)
                                                                {
                                                                    SecondaryStratum.Submit(Device, pascalWork, mPascalOutput[i]);
                                                                }
                                                            }
                                                            pascalStartNonce += (UInt32)mEthashGlobalWorkSizeArray[0] * mPascalRatio;

                                                            sw.Stop();
                                                            Speed = ((double)mEthashGlobalWorkSizeArray[0]) / sw.Elapsed.TotalSeconds * 0.75;
                                                            Device.TotalHashesPrimaryAlgorithm   += (double)mEthashGlobalWorkSizeArray[0] * 0.75;
                                                            SpeedSecondaryAlgorithm               = ((double)mEthashGlobalWorkSizeArray[0]) / sw.Elapsed.TotalSeconds * mPascalRatio;
                                                            Device.TotalHashesSecondaryAlgorithm += (double)mEthashGlobalWorkSizeArray[0] * mPascalRatio;
                                                            if (consoleUpdateStopwatch.ElapsedMilliseconds >= 10 * 1000)
                                                            {
                                                                MainForm.Logger("Device #" + DeviceIndex + ": " + String.Format("{0:N2} Mh/s (Ethash), ", Speed / (1000000)) + String.Format("{0:N2} Mh/s (Pascal)", SpeedSecondaryAlgorithm / (1000000)));
                                                                consoleUpdateStopwatch.Restart();
                                                            }
                                                        }
                                                    }
                                                } catch (Exception ex) {
                                                    MainForm.Logger("Exception in miner thread: " + ex.Message + ex.StackTrace);
                                                    Speed = 0;
                                                    if (UnrecoverableException.IsUnrecoverableException(ex))
                                                    {
                                                        this.UnrecoverableException = new UnrecoverableException(ex, Device);
                                                        Stop();
                                                    }
                                                    else
                                                    {
                                                        MainForm.Logger("Restarting miner thread...");
                                                        System.Threading.Thread.Sleep(Parameters.WaitTimeForRestartingMinerThreadInMilliseconds);
                                                    }
                                                } finally {
                                                    if (ethashDAGBuffer != null)
                                                    {
                                                        MemoryUsage -= ethashDAGBuffer.Size;
                                                        ethashDAGBuffer.Dispose();
                                                        ethashDAGBuffer = null;
                                                    }
                                                }
                                            }
            } catch (UnrecoverableException ex) {
                this.UnrecoverableException = ex;
            } catch (Exception ex) {
                this.UnrecoverableException = new UnrecoverableException(ex, Device);
            } finally {
                MarkAsDone();
                MemoryUsage = 0;
                if (program != null)
                {
                    program.Dispose();
                }
                program = null;
            }
        }
예제 #15
0
        override unsafe protected void MinerThread()
        {
            ComputeProgram program = null;

            try {
                Random r = new Random();

                MarkAsAlive();

                MainForm.Logger("Miner thread for Device #" + DeviceIndex + " started.");

                program = BuildProgram(
                    "lbry",
                    mLbryLocalWorkSizeArray[0],
                    "-O1 -DITERATIONS=" + mIterations,
                    "-DITERATIONS=" + mIterations,
                    "-DITERATIONS=" + mIterations);

                using (var lbrySearchKernel = program.CreateKernel("search_combined"))
                    using (var lbryInputBuffer = new ComputeBuffer <byte>(Context, ComputeMemoryFlags.ReadOnly, 112))
                        using (var lbryOutputBuffer = new ComputeBuffer <UInt32>(Context, ComputeMemoryFlags.ReadWrite, lbryOutputSize))
                            fixed(long *lbryGlobalWorkOffsetArrayPtr = mLbryGlobalWorkOffsetArray)
                            fixed(long *lbryGlobalWorkSizeArrayPtr = mLbryGlobalWorkSizeArray)
                            fixed(long *lbryLocalWorkSizeArrayPtr  = mLbryLocalWorkSizeArray)
                            fixed(byte *lbryInputPtr     = mLbryInput)
                            fixed(UInt32 * lbryOutputPtr = mLbryOutput)
                            while (!Stopped)
                            {
                                MarkAsAlive();

                                try
                                {
                                    lbrySearchKernel.SetMemoryArgument(0, lbryInputBuffer);
                                    lbrySearchKernel.SetMemoryArgument(1, lbryOutputBuffer);

                                    // Wait for the first lbryJob to arrive.
                                    int elapsedTime = 0;
                                    while ((Stratum == null || Stratum.GetJob() == null) && elapsedTime < Parameters.TimeoutForFirstJobInMilliseconds && !Stopped)
                                    {
                                        Thread.Sleep(100);
                                        elapsedTime += 100;
                                    }
                                    if (Stratum == null || Stratum.GetJob() == null)
                                    {
                                        throw new TimeoutException("Stratum server failed to send a new lbryJob.");
                                    }

                                    System.Diagnostics.Stopwatch consoleUpdateStopwatch = new System.Diagnostics.Stopwatch();
                                    LbryStratum.Work             lbryWork;
                                    LbryStratum.Job lbryJob;

                                    while (!Stopped && (lbryWork = Stratum.GetWork()) != null && (lbryJob = lbryWork.Job) != null)
                                    {
                                        MarkAsAlive();

                                        Array.Copy(lbryWork.Blob, mLbryInput, 112);
                                        UInt32 lbryStartNonce = (UInt32)(r.Next(0, int.MaxValue));
                                        UInt64 lbryTarget     = (UInt64)((double)0xffff0000UL / (Stratum.Difficulty / 256));
                                        lbrySearchKernel.SetValueArgument <UInt64>(3, lbryTarget);
                                        Queue.Write <byte>(lbryInputBuffer, true, 0, 112, (IntPtr)lbryInputPtr, null);

                                        consoleUpdateStopwatch.Start();

                                        while (!Stopped && Stratum.GetJob() != null && Stratum.GetJob().Equals(lbryJob))
                                        {
                                            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                                            sw.Start();

                                            MarkAsAlive();

                                            lbrySearchKernel.SetValueArgument <UInt32>(2, lbryStartNonce);

                                            // Get a new local extranonce if necessary.
                                            if (0xffffffffu - lbryStartNonce < (UInt32)mLbryGlobalWorkSizeArray[0] * mIterations)
                                            {
                                                break;
                                            }

                                            mLbryOutput[255] = 0; // mLbryOutput[255] is used as an atomic counter.
                                            Queue.Write <UInt32>(lbryOutputBuffer, true, 0, lbryOutputSize, (IntPtr)lbryOutputPtr, null);
                                            Queue.Execute(lbrySearchKernel, mLbryGlobalWorkOffsetArray, mLbryGlobalWorkSizeArray, mLbryLocalWorkSizeArray, null);
                                            Queue.Read <UInt32>(lbryOutputBuffer, true, 0, lbryOutputSize, (IntPtr)lbryOutputPtr, null);
                                            if (Stratum.GetJob() != null && Stratum.GetJob().Equals(lbryJob))
                                            {
                                                for (int i = 0; i < mLbryOutput[255]; ++i)
                                                {
                                                    String result = "";
                                                    for (int j = 0; j < 8; ++j)
                                                    {
                                                        UInt32 word = mLbryOutput[256 + i * 8 + j];
                                                        result += String.Format("{0:x2}{1:x2}{2:x2}{3:x2}", ((word >> 0) & 0xff), ((word >> 8) & 0xff), ((word >> 16) & 0xff), ((word >> 24) & 0xff));
                                                    }
                                                    Stratum.Submit(Device, lbryWork, mLbryOutput[i], result);
                                                }
                                            }
                                            lbryStartNonce += (UInt32)mLbryGlobalWorkSizeArray[0] * (uint)mIterations;

                                            sw.Stop();
                                            Speed = ((double)mLbryGlobalWorkSizeArray[0]) / sw.Elapsed.TotalSeconds * mIterations;
                                            Device.TotalHashesPrimaryAlgorithm += (double)mLbryGlobalWorkSizeArray[0] * mIterations;
                                            if (consoleUpdateStopwatch.ElapsedMilliseconds >= 10 * 1000)
                                            {
                                                MainForm.Logger("Device #" + DeviceIndex + ": " + String.Format("{0:N2} Mh/s (Lbry)", Speed / 1000000));
                                                consoleUpdateStopwatch.Restart();
                                            }
                                        }
                                    }
                                } catch (Exception ex) {
                                    MainForm.Logger("Exception in miner thread: " + ex.Message + ex.StackTrace);
                                    if (UnrecoverableException.IsUnrecoverableException(ex))
                                    {
                                        this.UnrecoverableException = new UnrecoverableException(ex, Device);
                                        Stop();
                                    }
                                }

                                Speed = 0;

                                if (!Stopped)
                                {
                                    MainForm.Logger("Restarting miner thread...");
                                    System.Threading.Thread.Sleep(Parameters.WaitTimeForRestartingMinerThreadInMilliseconds);
                                }
                            }
            } catch (UnrecoverableException ex) {
                this.UnrecoverableException = ex;
            } catch (Exception ex) {
                this.UnrecoverableException = new UnrecoverableException(ex, Device);
            } finally {
                MarkAsDone();
                MemoryUsage = 0;
                if (program != null)
                {
                    program.Dispose(); program = null;
                }
            }
        }
예제 #16
0
        override unsafe protected void MinerThread()
        {
            ComputeProgram program = null;

            try {
                Random r = new Random();

                MarkAsAlive();

                MainForm.Logger("Miner thread for Device #" + DeviceIndex + " started.");

                program = BuildProgram("pascal", mPascalLocalWorkSizeArray[0], "-O1", "", "");

                using (var pascalSearchKernel = program.CreateKernel("search"))
                    using (var pascalInputBuffer = new ComputeBuffer <byte>(Context, ComputeMemoryFlags.ReadOnly, sPascalInputSize))
                        using (var pascalOutputBuffer = new ComputeBuffer <UInt32>(Context, ComputeMemoryFlags.ReadWrite, sPascalOutputSize))
                            using (var pascalMidstateBuffer = new ComputeBuffer <byte>(Context, ComputeMemoryFlags.ReadOnly, sPascalMidstateSize))
                                fixed(long *pascalGlobalWorkOffsetArrayPtr = mPascalGlobalWorkOffsetArray)
                                fixed(long *pascalGlobalWorkSizeArrayPtr = mPascalGlobalWorkSizeArray)
                                fixed(long *pascalLocalWorkSizeArrayPtr  = mPascalLocalWorkSizeArray)
                                fixed(byte *pascalMidstatePtr            = mPascalMidstate)
                                fixed(byte *pascalInputPtr     = mPascalInput)
                                fixed(UInt32 * pascalOutputPtr = mPascalOutput)
                                while (!Stopped)
                                {
                                    MarkAsAlive();

                                    try
                                    {
                                        pascalSearchKernel.SetMemoryArgument(0, pascalInputBuffer);
                                        pascalSearchKernel.SetMemoryArgument(1, pascalOutputBuffer);
                                        pascalSearchKernel.SetMemoryArgument(4, pascalMidstateBuffer);

                                        // Wait for the first PascalJob to arrive.
                                        int elapsedTime = 0;
                                        while ((Stratum == null || Stratum.GetJob() == null) && elapsedTime < Parameters.TimeoutForFirstJobInMilliseconds && !Stopped)
                                        {
                                            Thread.Sleep(100);
                                            elapsedTime += 100;
                                        }
                                        if (Stratum == null || Stratum.GetJob() == null)
                                        {
                                            throw new TimeoutException("Stratum server failed to send a new PascalJob.");
                                        }

                                        System.Diagnostics.Stopwatch consoleUpdateStopwatch = new System.Diagnostics.Stopwatch();
                                        PascalStratum.Work           pascalWork;
                                        PascalStratum.Job            pascalJob;

                                        while (!Stopped && (pascalWork = Stratum.GetWork()) != null && (pascalJob = pascalWork.Job) != null)
                                        {
                                            MarkAsAlive();

                                            Array.Copy(pascalWork.Blob, mPascalInput, sPascalInputSize);
                                            CalculatePascalMidState();
                                            Queue.Write <byte>(pascalMidstateBuffer, true, 0, sPascalMidstateSize, (IntPtr)pascalMidstatePtr, null);
                                            UInt32 pascalStartNonce = (UInt32)(r.Next(0, int.MaxValue));
                                            UInt64 PascalTarget     = (UInt64)((double)0xffff0000UL / Stratum.Difficulty);
                                            pascalSearchKernel.SetValueArgument <UInt64>(3, PascalTarget);
                                            Queue.Write <byte>(pascalInputBuffer, true, 0, sPascalInputSize, (IntPtr)pascalInputPtr, null);

                                            consoleUpdateStopwatch.Start();

                                            while (!Stopped && Stratum.GetJob() != null && Stratum.GetJob().Equals(pascalJob))
                                            {
                                                System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                                                sw.Start();

                                                MarkAsAlive();

                                                pascalSearchKernel.SetValueArgument <UInt32>(2, pascalStartNonce);

                                                // Get a new local extranonce if necessary.
                                                if (0xffffffffu - pascalStartNonce < (UInt32)mPascalGlobalWorkSizeArray[0])
                                                {
                                                    break;
                                                }

                                                mPascalOutput[255] = 0; // mPascalOutput[255] is used as an atomic counter.
                                                Queue.Write <UInt32>(pascalOutputBuffer, true, 0, sPascalOutputSize, (IntPtr)pascalOutputPtr, null);
                                                Queue.Execute(pascalSearchKernel, mPascalGlobalWorkOffsetArray, mPascalGlobalWorkSizeArray, mPascalLocalWorkSizeArray, null);
                                                Queue.Read <UInt32>(pascalOutputBuffer, true, 0, sPascalOutputSize, (IntPtr)pascalOutputPtr, null);
                                                if (Stratum.GetJob() != null && Stratum.GetJob().Equals(pascalJob))
                                                {
                                                    for (int i = 0; i < mPascalOutput[255]; ++i)
                                                    {
                                                        Stratum.Submit(Device, pascalWork, mPascalOutput[i]);
                                                    }
                                                }
                                                pascalStartNonce += (UInt32)mPascalGlobalWorkSizeArray[0];

                                                sw.Stop();
                                                Speed = ((double)mPascalGlobalWorkSizeArray[0]) / sw.Elapsed.TotalSeconds;
                                                Device.TotalHashesPrimaryAlgorithm += (double)mPascalGlobalWorkSizeArray[0];
                                                if (consoleUpdateStopwatch.ElapsedMilliseconds >= 10 * 1000)
                                                {
                                                    MainForm.Logger("Device #" + DeviceIndex + ": " + String.Format("{0:N2} Mh/s (Pascal)", Speed / 1000000));
                                                    consoleUpdateStopwatch.Restart();
                                                }
                                            }
                                        }
                                    } catch (Exception ex) {
                                        MainForm.Logger("Exception in miner thread: " + ex.Message + ex.StackTrace);
                                        if (UnrecoverableException.IsUnrecoverableException(ex))
                                        {
                                            this.UnrecoverableException = new UnrecoverableException(ex, Device);
                                            Stop();
                                        }
                                    }

                                    Speed = 0;

                                    if (!Stopped)
                                    {
                                        MainForm.Logger("Restarting miner thread...");
                                        System.Threading.Thread.Sleep(Parameters.WaitTimeForRestartingMinerThreadInMilliseconds);
                                    }
                                }
                MarkAsDone();

                program.Dispose();
            } catch (UnrecoverableException ex) {
                if (program != null)
                {
                    program.Dispose();
                }
                this.UnrecoverableException = ex;
            } catch (Exception ex) {
                if (program != null)
                {
                    program.Dispose();
                }
                this.UnrecoverableException = new UnrecoverableException(ex, Device);
            }
        }
예제 #17
0
        override unsafe protected void MinerThread()
        {
            ComputeProgram program = null;

            try {
                ComputeDevice computeDevice = OpenCLDevice.GetComputeDevice();
                Random        r             = new Random();

                MarkAsAlive();

                //MainForm.Logger("Miner thread for Device #" + DeviceIndex + " started.");

                program = BuildProgram(
                    "lbry",
                    mLbryLocalWorkSizeArray[0],
                    "-O1 -DITERATIONS=" + mIterations,
                    "-DITERATIONS=" + mIterations,
                    "-DITERATIONS=" + mIterations);

                using (var mLbryInputBuffer = new ComputeBuffer <byte>(Context, ComputeMemoryFlags.ReadOnly, 112))
                    using (var mLbryOutputBuffer = new ComputeBuffer <UInt32>(Context, ComputeMemoryFlags.ReadWrite, lbryOutputSize))
                        using (var mLbrySearchKernel = program.CreateKernel("search_combined"))
                            fixed(long *lbryGlobalWorkOffsetArrayPtr = mLbryGlobalWorkOffsetArray)
                            fixed(long *lbryGlobalWorkSizeArrayPtr = mLbryGlobalWorkSizeArray)
                            fixed(long *lbryLocalWorkSizeArrayPtr  = mLbryLocalWorkSizeArray)
                            fixed(byte *lbryInputPtr     = mLbryInput)
                            fixed(UInt32 * lbryOutputPtr = mLbryOutput)
                            while (!Stopped)
                            {
                                MarkAsAlive();

                                try
                                {
                                    mLbrySearchKernel.SetMemoryArgument(0, mLbryInputBuffer);
                                    mLbrySearchKernel.SetMemoryArgument(1, mLbryOutputBuffer);

                                    while (!Stopped)
                                    {
                                        MarkAsAlive();

                                        mLbryInput = new byte[112];
                                        UInt32 lbryStartNonce = (UInt32)(r.Next(0, int.MaxValue));
                                        UInt64 lbryTarget     = (UInt64)((double)0xffff0000UL / (256 / 256));
                                        mLbrySearchKernel.SetValueArgument <UInt64>(3, lbryTarget);
                                        Queue.Write <byte>(mLbryInputBuffer, true, 0, 112, (IntPtr)lbryInputPtr, null);

                                        while (!Stopped)
                                        {
                                            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                                            sw.Start();

                                            MarkAsAlive();

                                            mLbrySearchKernel.SetValueArgument <UInt32>(2, lbryStartNonce);

                                            // Get a new local extranonce if necessary.
                                            if (0xffffffffu - lbryStartNonce < (UInt32)mLbryGlobalWorkSizeArray[0] * mIterations)
                                            {
                                                break;
                                            }

                                            mLbryOutput[255] = 0; // mLbryOutput[255] is used as an atomic counter.
                                            Queue.Write <UInt32>(mLbryOutputBuffer, true, 0, lbryOutputSize, (IntPtr)lbryOutputPtr, null);
                                            Queue.Execute(mLbrySearchKernel, mLbryGlobalWorkOffsetArray, mLbryGlobalWorkSizeArray, mLbryLocalWorkSizeArray, null);
                                            Queue.Read <UInt32>(mLbryOutputBuffer, true, 0, lbryOutputSize, (IntPtr)lbryOutputPtr, null);
                                            lbryStartNonce += (UInt32)mLbryGlobalWorkSizeArray[0] * (uint)mIterations;
                                        }
                                    }
                                } catch (Exception ex) {
                                    MainForm.Logger("Exception in dummy miner thread: " + ex.Message + ex.StackTrace);
                                    MainForm.Logger("Restarting dummy miner thread...");
                                }
                            }
            } catch (UnrecoverableException ex) {
                this.UnrecoverableException = ex;
            } catch (Exception ex) {
                this.UnrecoverableException = new UnrecoverableException(ex, Device);
            } finally {
                MarkAsDone();
                MemoryUsage = 0;
                if (program != null)
                {
                    program.Dispose();
                }
                program = null;
            }
        }
예제 #18
0
        override unsafe protected void MinerThread()
        {
            ComputeProgram       program = null;
            ComputeBuffer <byte> neoScryptGlobalCacheBuffer = null;

            try {
                Random r = new Random();

                MarkAsAlive();

                MainForm.Logger("Miner thread for Device #" + DeviceIndex + " started.");

                program = BuildProgram("neoscrypt", mNeoScryptLocalWorkSizeArray[0], "-O5 -legacy", "", "");

                neoScryptGlobalCacheBuffer = OpenCLDevice.RequestComputeByteBuffer(ComputeMemoryFlags.ReadWrite, (mNeoScryptGlobalWorkSizeArray[0] * 32768));
                MemoryUsage = sNeoScryptInputSize + sNeoScryptOutputSize + neoScryptGlobalCacheBuffer.Size;

                using (var neoScryptSearchKernel = program.CreateKernel("search"))
                    using (var neoScryptInputBuffer = new ComputeBuffer <byte>(Context, ComputeMemoryFlags.ReadOnly, sNeoScryptInputSize))
                        using (var neoScryptOutputBuffer = new ComputeBuffer <UInt32>(Context, ComputeMemoryFlags.ReadWrite, sNeoScryptOutputSize))
                            fixed(long *neoscryptGlobalWorkOffsetArrayPtr = mNeoScryptGlobalWorkOffsetArray)
                            fixed(long *neoscryptGlobalWorkSizeArrayPtr = mNeoScryptGlobalWorkSizeArray)
                            fixed(long *neoscryptLocalWorkSizeArrayPtr  = mNeoScryptLocalWorkSizeArray)
                            fixed(byte *neoscryptInputPtr     = mNeoScryptInput)
                            fixed(UInt32 * neoscryptOutputPtr = mNeoScryptOutput)
                            while (!Stopped)
                            {
                                MarkAsAlive();

                                try {
                                    neoScryptSearchKernel.SetMemoryArgument(0, neoScryptInputBuffer);
                                    neoScryptSearchKernel.SetMemoryArgument(1, neoScryptOutputBuffer);
                                    neoScryptSearchKernel.SetMemoryArgument(2, neoScryptGlobalCacheBuffer);

                                    // Wait for the first NeoScryptJob to arrive.
                                    int elapsedTime = 0;
                                    while ((Stratum == null || Stratum.GetJob() == null) && elapsedTime < Parameters.TimeoutForFirstJobInMilliseconds && !Stopped)
                                    {
                                        Thread.Sleep(100);
                                        elapsedTime += 100;
                                    }
                                    if (Stratum == null || Stratum.GetJob() == null)
                                    {
                                        throw new TimeoutException("Stratum server failed to send a new job.");
                                    }

                                    System.Diagnostics.Stopwatch consoleUpdateStopwatch = new System.Diagnostics.Stopwatch();
                                    NeoScryptStratum.Work        neoscryptWork;
                                    NeoScryptStratum.Job         neoscryptJob;

                                    while (!Stopped && (neoscryptWork = Stratum.GetWork()) != null && (neoscryptJob = neoscryptWork.Job) != null)
                                    {
                                        MarkAsAlive();

                                        Array.Copy(neoscryptWork.Blob, mNeoScryptInput, sNeoScryptInputSize);
                                        UInt32 neoscryptStartNonce = (UInt32)(r.Next(0, int.MaxValue));
                                        Queue.Write <byte>(neoScryptInputBuffer, true, 0, sNeoScryptInputSize, (IntPtr)neoscryptInputPtr, null);

                                        consoleUpdateStopwatch.Start();

                                        while (!Stopped && Stratum.GetJob() != null && Stratum.GetJob().Equals(neoscryptJob))
                                        {
                                            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                                            sw.Start();

                                            MarkAsAlive();

                                            UInt32 NeoScryptTarget = (UInt32)((double)0xffff0000U / (Stratum.Difficulty * 65536));
                                            neoScryptSearchKernel.SetValueArgument <UInt32>(3, NeoScryptTarget);
                                            mNeoScryptGlobalWorkOffsetArray[0] = neoscryptStartNonce;

                                            // Get a new local extranonce if necessary.
                                            if (0xffffffffu - neoscryptStartNonce < (UInt32)mNeoScryptGlobalWorkSizeArray[0])
                                            {
                                                break;
                                            }

                                            mNeoScryptOutput[255] = 0; // mNeoScryptOutput[255] is used as an atomic counter.
                                            Queue.Write <UInt32>(neoScryptOutputBuffer, true, 0, sNeoScryptOutputSize, (IntPtr)neoscryptOutputPtr, null);
                                            Queue.Execute(neoScryptSearchKernel, mNeoScryptGlobalWorkOffsetArray, mNeoScryptGlobalWorkSizeArray, mNeoScryptLocalWorkSizeArray, null);
                                            Queue.Read <UInt32>(neoScryptOutputBuffer, true, 0, sNeoScryptOutputSize, (IntPtr)neoscryptOutputPtr, null);
                                            if (Stratum.GetJob() != null && Stratum.GetJob().Equals(neoscryptJob))
                                            {
                                                for (int i = 0; i < mNeoScryptOutput[255]; ++i)
                                                {
                                                    Stratum.Submit(Device, neoscryptWork, mNeoScryptOutput[i]);
                                                }
                                            }
                                            neoscryptStartNonce += (UInt32)mNeoScryptGlobalWorkSizeArray[0];

                                            sw.Stop();
                                            Speed = ((double)mNeoScryptGlobalWorkSizeArray[0]) / sw.Elapsed.TotalSeconds;
                                            Device.TotalHashesPrimaryAlgorithm += (double)mNeoScryptGlobalWorkSizeArray[0];
                                            if (consoleUpdateStopwatch.ElapsedMilliseconds >= 10 * 1000)
                                            {
                                                MainForm.Logger("Device #" + DeviceIndex + ": " + String.Format("{0:N2} Kh/s (NeoScrypt)", Speed / 1000));
                                                consoleUpdateStopwatch.Restart();
                                            }
                                        }
                                    }
                                } catch (Exception ex) {
                                    MainForm.Logger("Exception in miner thread: " + ex.Message + ex.StackTrace);
                                    if (UnrecoverableException.IsUnrecoverableException(ex))
                                    {
                                        this.UnrecoverableException = new UnrecoverableException(ex, Device);
                                        Stop();
                                    }
                                }

                                Speed = 0;

                                if (!Stopped)
                                {
                                    MainForm.Logger("Restarting miner thread...");
                                    System.Threading.Thread.Sleep(Parameters.WaitTimeForRestartingMinerThreadInMilliseconds);
                                }
                            }
            } catch (UnrecoverableException ex) {
                this.UnrecoverableException = ex;
            } catch (Exception ex) {
                this.UnrecoverableException = new UnrecoverableException(ex, Device);
            } finally {
                MarkAsDone();
                MemoryUsage = 0;
                if (program != null)
                {
                    program.Dispose(); program = null;
                }
                if (neoScryptGlobalCacheBuffer != null)
                {
                    OpenCLDevice.ReleaseComputeByteBuffer(neoScryptGlobalCacheBuffer); neoScryptGlobalCacheBuffer = null;
                }
            }
        }
        override unsafe protected void MinerThread()
        {
            ComputeProgram       program           = null;
            ComputeBuffer <byte> statesBuffer      = null;
            ComputeBuffer <byte> scratchpadsBuffer = null;

            try {
                Random r          = new Random();
                var    openCLName = OpenCLDevice.GetComputeDevice().Name;
                var    GCN1       = openCLName == "Capeverde" || openCLName == "Hainan" || openCLName == "Oland" || openCLName == "Pitcairn" || openCLName == "Tahiti";

                MarkAsAlive();

                MainForm.Logger("Miner thread for Device #" + DeviceIndex + " started.");
                MainForm.Logger("NiceHash mode is " + (NiceHashMode ? "on" : "off") + ".");

                program = BuildProgram("cryptonight", localWorkSizeA[0], "-O5" + (GCN1 ? " -legacy" : ""), "", "");

                statesBuffer      = OpenCLDevice.RequestComputeByteBuffer(ComputeMemoryFlags.ReadWrite, 200 * globalWorkSizeA[0]);
                scratchpadsBuffer = OpenCLDevice.RequestComputeByteBuffer(ComputeMemoryFlags.ReadWrite, ((long)1 << 21) * globalWorkSizeA[0]);

                using (var searchKernel0 = program.CreateKernel("search"))
                    using (var searchKernel1 = program.CreateKernel("search1"))
                        using (var searchKernel2 = program.CreateKernel("search2"))
                            using (var searchKernel3 = program.CreateKernel("search3"))
                                using (var inputBuffer = new ComputeBuffer <byte>(Context, ComputeMemoryFlags.ReadOnly, 76))
                                    using (var outputBuffer = new ComputeBuffer <UInt32>(Context, ComputeMemoryFlags.ReadWrite, outputSize))
                                        using (var terminateBuffer = new ComputeBuffer <Int32>(Context, ComputeMemoryFlags.ReadWrite, 1))
                                            fixed(Int32 *terminatePtr = terminate)
                                            fixed(byte *inputPtr     = input)
                                            fixed(UInt32 * outputPtr = output)
                                            while (!Stopped)
                                            {
                                                MarkAsAlive();
                                                MemoryUsage =
                                                    200 * globalWorkSizeA[0]
                                                    + ((long)1 << 21) * globalWorkSizeA[0]
                                                    + 76 + outputSize + 1;

                                                try {
                                                    searchKernel0.SetMemoryArgument(0, inputBuffer);
                                                    searchKernel0.SetMemoryArgument(1, scratchpadsBuffer);
                                                    searchKernel0.SetMemoryArgument(2, statesBuffer);

                                                    searchKernel1.SetMemoryArgument(0, scratchpadsBuffer);
                                                    searchKernel1.SetMemoryArgument(1, statesBuffer);
                                                    searchKernel1.SetMemoryArgument(2, terminateBuffer);

                                                    searchKernel2.SetMemoryArgument(0, scratchpadsBuffer);
                                                    searchKernel2.SetMemoryArgument(1, statesBuffer);

                                                    searchKernel3.SetMemoryArgument(0, statesBuffer);
                                                    searchKernel3.SetMemoryArgument(1, outputBuffer);

                                                    // Wait for the first job to arrive.
                                                    int elapsedTime = 0;
                                                    while ((Stratum == null || Stratum.GetJob() == null) && elapsedTime < Parameters.TimeoutForFirstJobInMilliseconds && !Stopped)
                                                    {
                                                        Thread.Sleep(100);
                                                        elapsedTime += 100;
                                                    }
                                                    if (Stratum == null || Stratum.GetJob() == null)
                                                    {
                                                        throw new TimeoutException("Stratum server failed to send a new job.");
                                                    }

                                                    System.Diagnostics.Stopwatch consoleUpdateStopwatch = new System.Diagnostics.Stopwatch();
                                                    CryptoNightStratum.Work      work;
                                                    CryptoNightStratum.Job       job;

                                                    while (!Stopped && (work = Stratum.GetWork()) != null && (job = work.GetJob()) != null)
                                                    {
                                                        MarkAsAlive();

                                                        Array.Copy(Utilities.StringToByteArray(job.Blob), input, 76);
                                                        byte   localExtranonce = (byte)work.LocalExtranonce;
                                                        byte[] targetByteArray = Utilities.StringToByteArray(job.Target);
                                                        UInt32 startNonce;
                                                        if (NiceHashMode)
                                                        {
                                                            startNonce = ((UInt32)input[42] << (8 * 3)) | ((UInt32)localExtranonce << (8 * 2)) | (UInt32)(r.Next(0, int.MaxValue) & (0x0000ffffu));
                                                        }
                                                        else
                                                        {
                                                            startNonce = ((UInt32)localExtranonce << (8 * 3)) | (UInt32)(r.Next(0, int.MaxValue) & (0x00ffffffu));
                                                        }
                                                        UInt32 target = ((UInt32)targetByteArray[0] << 0)
                                                                        | ((UInt32)targetByteArray[1] << 8)
                                                                        | ((UInt32)targetByteArray[2] << 16)
                                                                        | ((UInt32)targetByteArray[3] << 24);
                                                        searchKernel3.SetValueArgument <UInt32>(2, target);

                                                        Queue.Write <byte>(inputBuffer, true, 0, 76, (IntPtr)inputPtr, null);

                                                        consoleUpdateStopwatch.Start();

                                                        while (!Stopped && Stratum.GetJob() != null && Stratum.GetJob().Equals(job))
                                                        {
                                                            MarkAsAlive();

                                                            globalWorkOffsetA[0] = globalWorkOffsetB[0] = startNonce;

                                                            // Get a new local extranonce if necessary.
                                                            if (NiceHashMode)
                                                            {
                                                                if ((startNonce & 0xffff) + (UInt32)globalWorkSizeA[0] >= 0x10000)
                                                                {
                                                                    break;
                                                                }
                                                            }
                                                            else
                                                            {
                                                                if ((startNonce & 0xffffff) + (UInt32)globalWorkSizeA[0] >= 0x1000000)
                                                                {
                                                                    break;
                                                                }
                                                            }

                                                            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                                                            sw.Start();
                                                            output[255] = 0; // output[255] is used as an atomic counter.
                                                            Queue.Write <UInt32>(outputBuffer, true, 0, outputSize, (IntPtr)outputPtr, null);
                                                            terminate[0] = 0;
                                                            Queue.Write <Int32>(terminateBuffer, true, 0, 1, (IntPtr)terminatePtr, null);
                                                            Queue.Execute(searchKernel0, globalWorkOffsetA, globalWorkSizeA, localWorkSizeA, null);
                                                            Queue.Finish();
                                                            if (Stopped)
                                                            {
                                                                break;
                                                            }
                                                            Queue.Execute(searchKernel1, globalWorkOffsetB, globalWorkSizeB, localWorkSizeB, null);
                                                            Queue.Finish();
                                                            if (Stopped)
                                                            {
                                                                break;
                                                            }
                                                            Queue.Execute(searchKernel2, globalWorkOffsetA, globalWorkSizeA, localWorkSizeA, null);
                                                            Queue.Finish();
                                                            if (Stopped)
                                                            {
                                                                break;
                                                            }
                                                            Queue.Execute(searchKernel3, globalWorkOffsetB, globalWorkSizeB, localWorkSizeB, null);
                                                            Queue.Finish(); // Run the above statement before leaving the current local scope.
                                                            if (Stopped)
                                                            {
                                                                break;
                                                            }

                                                            Queue.Read <UInt32>(outputBuffer, true, 0, outputSize, (IntPtr)outputPtr, null);
                                                            if (Stratum.GetJob() != null && Stratum.GetJob().Equals(job))
                                                            {
                                                                for (int i = 0; i < output[255]; ++i)
                                                                {
                                                                    String result = "";
                                                                    for (int j = 0; j < 8; ++j)
                                                                    {
                                                                        UInt32 word = output[256 + i * 8 + j];
                                                                        result += String.Format("{0:x2}{1:x2}{2:x2}{3:x2}", ((word >> 0) & 0xff), ((word >> 8) & 0xff), ((word >> 16) & 0xff), ((word >> 24) & 0xff));
                                                                    }
                                                                    Stratum.Submit(Device, job, output[i], result);
                                                                }
                                                            }
                                                            startNonce += (UInt32)globalWorkSizeA[0];

                                                            sw.Stop();
                                                            Speed = ((double)globalWorkSizeA[0]) / sw.Elapsed.TotalSeconds;
                                                            Device.TotalHashesPrimaryAlgorithm += (double)globalWorkSizeA[0];
                                                            if (consoleUpdateStopwatch.ElapsedMilliseconds >= 10 * 1000)
                                                            {
                                                                MainForm.Logger("Device #" + DeviceIndex + " (CryptoNight): " + String.Format("{0:N2} h/s", Speed));
                                                                consoleUpdateStopwatch.Restart();
                                                            }
                                                        }
                                                    }
                                                } catch (Exception ex) {
                                                    if (statesBuffer != null)
                                                    {
                                                        OpenCLDevice.ReleaseComputeByteBuffer(statesBuffer); statesBuffer = null;
                                                    }
                                                    if (scratchpadsBuffer != null)
                                                    {
                                                        OpenCLDevice.ReleaseComputeByteBuffer(scratchpadsBuffer); scratchpadsBuffer = null;
                                                    }
                                                    MainForm.Logger("Exception in miner thread: " + ex.Message + ex.StackTrace);
                                                    if (UnrecoverableException.IsUnrecoverableException(ex))
                                                    {
                                                        this.UnrecoverableException = new UnrecoverableException(ex, Device);
                                                        Stop();
                                                    }
                                                }

                                                Speed = 0;

                                                if (!Stopped)
                                                {
                                                    MainForm.Logger("Restarting miner thread...");
                                                    System.Threading.Thread.Sleep(Parameters.WaitTimeForRestartingMinerThreadInMilliseconds);
                                                }
                                            }
            } catch (UnrecoverableException ex) {
                this.UnrecoverableException = ex;
            } catch (Exception ex) {
                this.UnrecoverableException = new UnrecoverableException(ex, Device);
            } finally {
                MarkAsDone();
                MemoryUsage = 0;
                if (program != null)
                {
                    program.Dispose(); program = null;
                }
                if (statesBuffer != null)
                {
                    OpenCLDevice.ReleaseComputeByteBuffer(statesBuffer); statesBuffer = null;
                }
                if (scratchpadsBuffer != null)
                {
                    OpenCLDevice.ReleaseComputeByteBuffer(scratchpadsBuffer); scratchpadsBuffer = null;
                }
            }
        }
예제 #20
0
        public void Run(ComputeContext context, TextWriter log)
        {
            try
            {
                // Create the arrays and fill them with random data.
                int     count = 10;
                float[] arrA  = new float[count];
                float[] arrB  = new float[count];
                float[] arrC  = new float[count];

                Random rand = new Random();
                for (int i = 0; i < count; i++)
                {
                    arrA[i] = (float)(rand.NextDouble() * 100);
                    arrB[i] = (float)(rand.NextDouble() * 100);
                }

                // Create the input buffers and fill them with data from the arrays.
                // Access modifiers should match those in a kernel.
                // CopyHostPointer means the buffer should be filled with the data provided in the last argument.
                ComputeBuffer <float> a = new ComputeBuffer <float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, arrA);
                ComputeBuffer <float> b = new ComputeBuffer <float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, arrB);

                // The output buffer doesn't need any data from the host. Only its size is specified (arrC.Length).
                ComputeBuffer <float> c = new ComputeBuffer <float>(context, ComputeMemoryFlags.WriteOnly, arrC.Length);

                // Create and build the opencl program.
                program = new ComputeProgram(context, clProgramSource);
                program.Build(null, null, null, IntPtr.Zero);

                // Create the kernel function and set its arguments.
                ComputeKernel kernel = program.CreateKernel("VectorAdd");
                kernel.SetMemoryArgument(0, a);
                kernel.SetMemoryArgument(1, b);
                kernel.SetMemoryArgument(2, c);

                // Create the event wait list. An event list is not really needed for this example but it is important to see how it works.
                // Note that events (like everything else) consume OpenCL resources and creating a lot of them may slow down execution.
                // For this reason their use should be avoided if possible.
                ComputeEventList eventList = new ComputeEventList();

                // Create the command queue. This is used to control kernel execution and manage read/write/copy operations.
                ComputeCommandQueue commands = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None);

                // Execute the kernel "count" times. After this call returns, "eventList" will contain an event associated with this command.
                // If eventList == null or typeof(eventList) == ReadOnlyCollection<ComputeEventBase>, a new event will not be created.
                commands.Execute(kernel, null, new long[] { count }, null, eventList);

                // Read back the results. If the command-queue has out-of-order execution enabled (default is off), ReadFromBuffer
                // will not execute until any previous events in eventList (in our case only eventList[0]) are marked as complete
                // by OpenCL. By default the command-queue will execute the commands in the same order as they are issued from the host.
                // eventList will contain two events after this method returns.
                commands.ReadFromBuffer(c, ref arrC, false, eventList);

                // A blocking "ReadFromBuffer" (if 3rd argument is true) will wait for itself and any previous commands
                // in the command queue or eventList to finish execution. Otherwise an explicit wait for all the opencl commands
                // to finish has to be issued before "arrC" can be used.
                // This explicit synchronization can be achieved in two ways:

                // 1) Wait for the events in the list to finish,
                //eventList.Wait();

                // 2) Or simply use
                commands.Finish();

                // Print the results to a log/console.
                for (int i = 0; i < count; i++)
                {
                    log.WriteLine("{0} + {1} = {2}", arrA[i], arrB[i], arrC[i]);
                }

                // cleanup commands
                commands.Dispose();

                // cleanup events
                foreach (ComputeEventBase eventBase in eventList)
                {
                    eventBase.Dispose();
                }
                eventList.Clear();

                // cleanup kernel
                kernel.Dispose();

                // cleanup program
                program.Dispose();

                // cleanup buffers
                a.Dispose();
                b.Dispose();
                c.Dispose();
            }
            catch (Exception e)
            {
                log.WriteLine(e.ToString());
            }
        }