M1 MacでのErgo GPUマイニング

# M1での ERGO GPUマイニング
M1 Mac miniで[Autolykos2_AMD_Miner](https://github.com/mhssamadani/Autolykos2_AMD_Miner)を使用してAutolykos2(Ergo)のGPUマイニングをしてみました。

ハッシュレートは5.5 MH/sぐらい、消費電力はほぼ8-9Wです(ただし時々15Wぐらいになるときがあります)。現時点(2021/6/10)では、[Nanopool](https://nanopool.org/)での実測値は4.7MH/s程度で一日0.012ERGO(12円)ぐらいのようです。1kWh30円とすると電気代が一日6円ぐらいなので数円程度の利益はでるようです。

Nanopoolを使って説明します。Nanopoolの場合、Ergoのマイニング報酬を送付するErgoのウォレットが別途必要なので、[CoinEx](https://www.coinex.com/)等で用意してください。

## 更新履歴
- 2021/9/27 パッチがおかしいので修正
- 2021/9/26 M1向けに削除したAMD GPU用のOpenCLコードを戻したパッチを追加(動作未確認)
- 2021/9/25 OpenSSL関係を修正し環境変数の設定を追加とpkg-configのインストールを追加
- 2021/7/4 元のコードの改行コードの関係かなにかでパッチがうまく当たらないようなのでパッチを修正

## Autolykos2_AMD_MinerとErgoStratumProxyのビルド
Autolykos2_AMD_MinerでマイニングするためにはErgoマイナー本体の他に、Stratumでマイニングプールに接続するためのProxyである[ErgoStratumProxy](https://github.com/mhssamadani/ErgoStratumProxy)も必要なので、そちらもビルドします。

### 準備
ターミナルを起動してください。~/Downloads/以下で作業します。

```
$ cd ~/Downloads/
```

XcodeとCommand line tools for Xcodeが未インストールならば[App StoreからXcodeをインストールし](https://apps.apple.com/jp/app/xcode/id497799835)、ターミナル上でCommand line tools for Xcodeをインストールしてください。

```
$ xcode-select --install
```

### Autolykos2_AMD_Minerのビルド
OpenSSLが必要です。ErgoStratumProxyにNode.jsも必要なのでbrew経由で一緒にインストールし、必要な環境変数を設定します。

brewが未インストールならbrewをインストールし、brew経由でpkg-configとOpenSSLとNode.jsをインストールしてください(2021/9/25追記)。

```
$ arch -arm64e /bin/bash -c "$(curl -fsSL $ https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
$ export PATH=/opt/homebrew/bin:$PATH
```

```
$ brew install openssl node pkg-config
```

OpenSSLにパスを通します(2021/9/25追記)。

```
$ export PKG_CONFIG_PATH=/opt/homebrew/opt/openssl/lib/pkgconfig
```

そのままではAutolykos2_AMD_MinerはM1では動作しないので、[自作のパッチ](https://github.com/asfdrwe/misc/blob/main/Autolykos2_AMD_Miner-m1-20210704.patch)を使用します(2021/7/4修正)。

修正箇所は、macOS用のMakefileの追加(Ubuntu用のMakefileを元にstd=c++11オプションの追加やOpenSSLとOpenCLを適切にリンクできるように修正)、ローテート関係のAMD専用OpenCLのコードの削除、OpenCLのインクルードファイルCL/cl.hとL/cl_ext.hをOpenCL/cl.hとOpenCL/cl_ext.hに変更、GPUの状態を取得するコードの削除、GPUのメモリ不足で実行を止める箇所を削除、AMDのGPUだけでなくAppleのGPUも認識するようにするコードの追加です。

git経由でファイルを取得します。

```
$ git clone https://github.com/mhssamadani/Autolykos2_AMD_Miner.git
$ cd Autolykos2_AMD_Miner
```

パッチを取得して当てます。

```
$ curl -o Autolykos2_AMD_Miner-m1-20210704.patch https://raw.githubusercontent.com/asfdrwe/misc/main/Autolykos2_AMD_Miner-m1-20210704.patch
$ patch -p1 < Autolykos2_AMD_Miner-m1-20210704.patch
```

(2021/7/4新しいパッチに修正)




ビルドします。

```
$ cd macOS
$ make
```

一旦~/Downloads/に戻ります。

```
$ cd ../..
```

### ErgoStratumProxyのビルド
ErgoStratumProxyをビルドします。Node.jsが必要です。

git経由でErgoStratumProxyのファイルを取得します。

```
$ git clone https://github.com/mhssamadani/ErgoStratumProxy.git
$ cd ErgoStratumProxy
```

npm経由で必要なモジュールをインストールします。

```
$ npm install
```

一旦~/Downloads/に戻ります。

```
$ cd ..
```

### Autolykos2_AMD_Minerマイニングの実行
Autolykos2_AMD_MinerとErgoStratumProxyの両方を動かす必要があるので、ターミナルをもう一つ起動してください。

最初に片方のターミナルでErgoStratumProxyを実行します。

~/Downloads/ErgoStratumProxyに移動してErgoStratumProxyを実行します。

ErgoStratumProxyがプールとやり取りするので、送付先ウォレット等の設定は
ErgoStratumProxyで行います。Nanopoolでergo-asia1.nanopool.orgを使用する場合は次のように指定します。

```
$ cd ~/Downloads/ErgoStratumProxy
$ node client.js -s ergo-asia1.nanopool.org -p 11111 -u Ergoのウォレットアドレス(例えばCoinEXのアドレス).ワーカー名(何でもいい) -w メールアドレス(Nanopoolではメールアドレスをパスワードのように使用)
```

補足: 
うまく動くかわかりませんが、上記のAutolykos2_AMD_Minerのパッチは、M1のGPUで動くようにするためにOpenCLのビット整列のAMD拡張を無効にして汎用コードを使うようにしているので、Intel MacでAMDのGPUを使う場合は代わりにAMD拡張を有効にしたこちらのパッチを当てた方がハッシュレートが上がるかもしれません(2021/9/26追記、2021/9/27修正)。

```
$ curl -o Autolykos2_AMD_Miner-x86-20210927.patch https://raw.githubusercontent.com/asfdrwe/misc/main/Autolykos2_AMD_Miner-x86-20210927.patch
$ patch -p1 < Autolykos2_AMD_Miner-x86-20210927.patch
```

2021/7/4時点で試した範囲ではErgoStratumProxyは[Nicehash](https://www.nicehash.com/)にはうまくつながらないようです。(2021/7/4追記)

もう一方のターミナルでAutolykos2_AMD_Minerを実行します。

2021/7/4時点では最新のOSに更新している場合以下の環境変数を設定しなくてもOpenCLのコードは問題なく動くようになっています。(2021/7/4追記)

~~日本語環境でOpenCLのバックスラッシュを円記号として扱うcl2Metalのバグ回避のために、次のように環境変数`__CF_USER_TEXT_ENCODING`を英語設定にしてください。~~

~~uidをidコマンドで確認し`uidが501(16進数で0x1F5)の場合はこのように設定します。~~

```
$ id
uid=501(asfdrwe) gid=20(staff) groups=20(staff),...

$ export __CF_USER_TEXT_ENCODING=0x1F5:0x1:0xE
```

~/Downloads/Autolykos2_AMD_Minerに移動してmacOS以下にあるErgoOpenCLを実行します。OCLdecs.h, OCLdefs.h, MiningKernel.cl, PreHashKernel.clが存在するディレクトリでないとErgoOpenCLが実行できないので気をつけてください。

```
$ cd ~/Downloads/Autolykos2_AMD_Miner
$ macOS/ErgoOpenCL
```

### 実行例

#### ErgoStratumProxy
```
Ergo Stratum Proxy
Running at http://localhost:3000
--------------------------------------------------

[CONNECTION] Connected to server.
[SUBSCRIBE] Nonce: b4ee, nonce size: 6
[WORKER] Worker authorized.
[DIFFICULTY] New difficulty: 1
[JOB] New job received. Job ID: 1ef2, difficulty: 1, height: 505799
[JOB] New job received. Job ID: 1ef3, difficulty: 1, height: 505799

----------------------------------------
Accepted shares: 0
Rejected shares: 0
Time elapsed: 0:01
----------------------------------------

[JOB] New job received. Job ID: 1ef4, difficulty: 1, height: 505800

----------------------------------------
Accepted shares: 0
Rejected shares: 0
Time elapsed: 0:02
----------------------------------------

[JOB] New job received. Job ID: 1ef5, difficulty: 1, height: 505800

----------------------------------------
Accepted shares: 0
Rejected shares: 0
Time elapsed: 0:03
----------------------------------------
...
```

SHAREが見つかると

```
...
[JOB] New job received. Job ID: 1f08, difficulty: 1, height: 505807

----------------------------------------
Accepted shares: 0
Rejected shares: 0
Time elapsed: 0:19
----------------------------------------

[JOB] New job received. Job ID: 1f09, difficulty: 1, height: 505808
[SHARE] Share accepted.

----------------------------------------
Accepted shares: 1
Rejected shares: 0
Time elapsed: 0:20
----------------------------------------
...
```

#### Autolykos2_AMD_Miner

```
2021-06-08 14:39:53,949 INFO [main thread] Number Of AMD GPUs: 1
2021-06-08 14:39:53,950 INFO [main thread] Using configuration file ./config.json
2021-06-08 14:39:53,950 INFO [main thread] Block getting URL:
   http://127.0.0.1:3000/mining/candidate
2021-06-08 14:39:53,950 INFO [main thread] Solution posting URL:
   http://127.0.0.1:3000/mining/solution
2021-06-08 14:39:54,956 INFO [GPU 0 miner] Gpu 0 Started
2021-06-08 14:39:54,956 INFO [GPU 0 miner] GPU 0 mem_size: 5461  (MB) , max_mem_alloc_size: 1024 (MB) 
2021-06-08 14:39:54,956 ERROR [GPU 0 miner] GPU 0 Not enough GPU memory for mining, minimum 2.8 GiB needed
2021-06-08 14:39:54,956 INFO [GPU 0 miner] GPU 0 allocating memory
2021-06-08 14:39:54,967 INFO [main thread] Got new block in main thread, block data: {"MSG":"7184ED6E4AB1A7725A954C39345C3B44191B2166109D44377053EB1AF8ED2341","B":11579208923731619542357098500868790785326998466564056403945758400790,"EXTRANONCE1":"B4EE","EXTRANONCE2SIZE":6,"HEIGHT":505799}
2021-06-08 14:39:56,188 INFO [GPU 0 miner] GPU 0 read new block data
2021-06-08 14:40:18,637 INFO [GPU 0 miner] Prehash time: 22448 ms
2021-06-08 14:41:01,553 INFO [main thread] Average curling time 1.172 ms
2021-06-08 14:41:01,554 INFO [main thread] Current block candidate: {"MSG":"7184ED6E4AB1A7725A954C39345C3B44191B2166109D44377053EB1AF8ED2341","B":11579208923731619542357098500868790785326998466564056403945758400790,"EXTRANONCE1":"B4EE","EXTRANONCE2SIZE":6,"HEIGHT":505799}
2021-06-08 14:41:01,554 INFO [main thread] Average hashrates: GPU0 3.63527 MH/s Total 3.63527 MH/s 
2021-06-08 14:41:14,204 INFO [main thread] Got new block in main thread, block data: {"MSG":"6DE748DE124770DD5BD59FE47BF28D44DB563C53D0CAD52A6F52594FC50C7F84","B":11579208923731619542357098500868790785326998466564056403945758400790,"EXTRANONCE1":"B4EE","EXTRANONCE2SIZE":6,"HEIGHT":505800}
2021-06-08 14:41:14,678 INFO [GPU 0 miner] GPU 0 blockId != info->blockId.load 
2021-06-08 14:41:14,679 INFO [GPU 0 miner] GPU 0 read new block data
2021-06-08 14:41:36,911 INFO [GPU 0 miner] Prehash time: 22231 ms
2021-06-08 14:42:07,335 INFO [main thread] Average curling time 1.123 ms
2021-06-08 14:42:07,336 INFO [main thread] Current block candidate: {"MSG":"6DE748DE124770DD5BD59FE47BF28D44DB563C53D0CAD52A6F52594FC50C7F84","B":11579208923731619542357098500868790785326998466564056403945758400790,"EXTRANONCE1":"B4EE","EXTRANONCE2SIZE":6,"HEIGHT":505800}
2021-06-08 14:42:07,336 INFO [main thread] Average hashrates: GPU0 3.61403 MH/s Total 3.61403 MH/s 
2021-06-08 14:43:13,028 INFO [main thread] Average curling time 1.06 ms
2021-06-08 14:43:13,029 INFO [main thread] Current block candidate: {"MSG":"6DE748DE124770DD5BD59FE47BF28D44DB563C53D0CAD52A6F52594FC50C7F84","B":11579208923731619542357098500868790785326998466564056403945758400790,"EXTRANONCE1":"B4EE","EXTRANONCE2SIZE":6,"HEIGHT":505800}
2021-06-08 14:43:13,030 INFO [main thread] Average hashrates: GPU0 5.53864 MH/s Total 5.53864 MH/s 
2021-06-08 14:44:01,091 INFO [main thread] Got new block in main thread, block data: {"MSG":"E65C54C8C629CFC9DCE0AC1A3C0F3F4943BB7828E59FA2862A491A63D0886311","B":11579208923731619542357098500868790785326998466564056403945758400790,"EXTRANONCE1":"B4EE","EXTRANONCE2SIZE":6,"HEIGHT":505801}
2021-06-08 14:44:01,528 INFO [GPU 0 miner] GPU 0 blockId != info->blockId.load 
2021-06-08 14:44:01,529 INFO [GPU 0 miner] GPU 0 read new block data
2021-06-08 14:44:06,344 INFO [main thread] Got new block in main thread, block data: {"MSG":"5D86BE875FF83C4A6E049714C07AE286298D0594FF6EB3A9BBD92FD46798381B","B":11579208923731619542357098500868790785326998466564056403945758400790,"EXTRANONCE1":"B4EE","EXTRANONCE2SIZE":6,"HEIGHT":505802}
2021-06-08 14:44:18,666 INFO [main thread] Average curling time 1.025 ms
2021-06-08 14:44:18,666 INFO [main thread] Current block candidate: {"MSG":"5D86BE875FF83C4A6E049714C07AE286298D0594FF6EB3A9BBD92FD46798381B","B":11579208923731619542357098500868790785326998466564056403945758400790,"EXTRANONCE1":"B4EE","EXTRANONCE2SIZE":6,"HEIGHT":505802}
2021-06-08 14:44:18,666 INFO [main thread] Average hashrates: GPU0 5.57353 MH/s Total 5.57353 MH/s 
2021-06-08 14:44:23,761 INFO [GPU 0 miner] Prehash time: 22230 ms
2021-06-08 14:44:24,433 INFO [GPU 0 miner] GPU 0 blockId != info->blockId.load 
2021-06-08 14:44:24,433 INFO [GPU 0 miner] GPU 0 read new block data
...
```

SHAREが見つかると

```
...
2021-06-08 14:59:28,134 INFO [sender thread] Some GPU found and trying to POST a share: 
2021-06-08 14:59:28,134 INFO [sender thread] POST request {"n":"B4EE000001CF4E13"}
2021-06-08 14:59:28,153 INFO [sender thread] Node response:{"status":"OK"}
...
```

### 雑記
消費電力はだいたい8-9Wで動作するのですが時々15Wに増えます。ハッシュレートも5.5 MH/sぐらいですが時々変動します。

[XMRig](https://qiita.com/asfdrwe/items/53e7e10a47c43652ae5b)のRandomXと同時に動かすこともできるのですが、なぜかハッシュレートが少し上がって6.2 MH/sぐらいになります。消費電力は21-23Wですが時々32Wに増えます。それとRandomXのハッシュレートはRandomX+KAWPOWの時より少し上がって1900-2000 H/sぐらいで動きます。

何か不思議な挙動に感じます。

[Team Red MinerのAUTOLYKOSのチューニング文書](https://github.com/todxx/teamredminer/blob/master/doc/AUTOLYKOS_TUNING.txt)に

```
Autolykos2 is a memory-intensive low/medium power algo.
...
This algo accesses mem in 32 byte chunks.
訳: Autolykos2はメモリ集約型で低中消費電力のアルゴリズムです。
このアルゴリズムは32バイト単位でメモリにアクセスします。
```
とあります。Autolykos2のメモリ関係からこのような挙動になっているのかなと思っています。