HPCメモ

HPC(High Performance Computing)に関連したりしなかったりすることのメモ書き

echo

みんな大好きなecho(1)ですが、最近Amazonから物理デバイスとして発売されたようですね。



しょうもないボケはさておき、Amazon Echoの発表と合わせてMusic Unlimitedという新サービスを開始するなど、スマートスピーカーの売り込みを頑張ってるようですね。
pc.watch.impress.co.jp

個人的には、ここ数年はAmazon Prime会員で特に最近はほとんど音楽はkindle FireからPrime musicの音楽を聴くばっかりという生活なので、echoはこのスピーカー機能だけでも買いたいんですが、ひとつ重大な問題があります。

amazon musicの検索機能がクラシック音楽に対して弱すぎる

発表資料のなかに「アレクサ、スピッツをかけて」なんてのが載ってましたが、クラシック音楽でこれをやるとたぶん使いものになりません。
というのも、曲名も人名も長すぎるのでメジャーな曲やら作曲者の場合こんな感じで俗称というか略語がついてるんですが、amazon musicで検索してもまったくひっかからないんです。
クラシック音楽の曲名の俗称の一覧 - Wikipedia

例えば、チャイコフスキーが作曲したヴァイオリン協奏曲は通常「チャイコン」と呼ばれますがこれで検索するとまったくひっかかりません。
f:id:n_so5:20171109095455p:plain

それどころか、チャイコフスキーで検索するのとTchaikovskyで検索するのでは結果が違うというていたらくです。
f:id:n_so5:20171109095549p:plain
f:id:n_so5:20171109095553p:plain

また、ストラヴィンスキーが作曲した「春の祭典」という曲は「ハルサイ」と呼ばれてますが、これで検索するとナクソスから出てるネタアルバム「ハルサイとか聴いてるヤバい奴はクラスで俺だけ。」しかひっかかりません。
f:id:n_so5:20171109100516p:plain


amazon echo(に限らずスマートスピーカー)と音楽再生サービスの組合せには大いに期待してるんですが、このままでは「年末に第九でも聴くかー」という状況で「アレクサ、ベートーベンの交響曲第9番をかけて」と言わなくちゃならんようなコレジャナイ未来が待ってそうなので、今朝からひたすらAlexa Skills Kitのドキュメントを読み漁ってます。

https://developer.amazon.com/ja/alexa-skills-kit

音楽再生の要求に対して、検索キーワードを俗称ー>正式名称に変換するパイプを作れれば十分目的は果たしそうなんだけど、そういう機能は無いのかなぁ

node.jsのpromisify

ここ数ヶ月nodejsでお仕事をしていて、こんな感じのコードをいくつか作ったんですが、昨日初めてutil.promisifyの存在を知りました orz

function hoge(filename){
  return new Promise(function(resolve, reject){
    fs.readFile(filename, function(err,data){
      if(err){
         reject(err);
      }else{
         resolve(data);
      }
    });
  });
}

このコードが次の1行で済んじゃうという・・・

util.promisify(fs.readFile)

実装はこんな感じです。
github.com
やってることは、

  1. 引数で渡された関数を実行
  2. callbackの第1引数がfalsyだったらreject
  3. そうでなければcallbackの第2引数以降を引数にしてresolve

引数で渡された関数が例外を投げた時にもrejectしたり、callbackの第3引数以降もまとめてresolveの引数に渡してたりと上でやってることよりさらに汎用的な作りになってます。


要はいままで劣化した車輪を再発明してたようで・・・

ケーブルオーガナイザ

結構前の話ですが、IKEAで売ってる高さ調節のできるワークデスクを導入しました。*1*2

www.ikea.com

ほぼ高さ調節用のハンドルがついてるだけのシンプルな作りなのは良いんですが、仕事道具を並べたらさっそく机の上までスパゲッティに侵されました。*3

f:id:n_so5:20170719130148j:plain

そんなこと百も承知のIKEA様は机売り場のそこかしこにこんな製品を売ってたわけですが、今さらIKEAまで買いに行くのも負けた気がするので100均グッズで自作してみました。

www.ikea.com



用意したのは、ダイソーC型クランプ&ワイヤーネットです。

f:id:n_so5:20170719130614j:plain

クランプでワイヤーネットを机の天板からブラ下げて

f:id:n_so5:20170719134651j:plain

タイラップでケーブル&ACアダプタを固定すれば完成!

f:id:n_so5:20170719142831j:plain

クランプの上部が机の上に飛び出しているので、端の方にモノを置くと干渉しますが、合わせて350円(税抜)かと思うと許せます :)

*1:約2万円のお値段ですが、配送を頼むと送料が1万円を越えました・・・orz

*2:それでも格安

*3:足元はもっと大変なことになってますw

ansibleで改行コードの変換

ansilbleのplaybookの中でpatchモジュールを使って転送したファイルにpatchをあててたのがあったのですが、なぜかパッチファイルと適用対象ファイルの改行コードがLFの時は動作するのに、CRLFだと駄目という現象が起きたので、急遽playbookの中で改行コードを変換する方法を調べてみました。

使うモジュールはこちら
replace - Replace all instances of a particular string in a file using a back-referenced regular expression. — Ansible Documentation

テスト用にこんな内容のファイルを用意します。中身は一緒で改行コードがLFのものとCRLFのものです。

$ cat org_crlf.txt 
hoge
hoge
$ cat org_lf.txt 
hoge
hoge
$ file hoge_*
hoge_crlf_org.txt: ASCII text, with CRLF line terminators
hoge_lf_org.txt:   ASCII text

でもって、次のようなplaybookを作って実行します。

- hosts: 127.0.0.1
  connection: local
  strategy: debug
  tasks:
    - copy: 
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
      with_items:
        - {src: "org_crlf.txt", dest: "./hoge_crlf_to_lf.txt"}
        - {src: "org_crlf.txt", dest: "./hoge_crlf_to_crlf.txt"}
        - {src: "org_lf.txt",   dest: "./hoge_lf_to_lf.txt"}
        - {src: "org_lf.txt",   dest: "./hoge_lf_to_crlf.txt"}

    - name: CRLF to LF by replace
      replace:
        dest: "{{ item }}"
        regexp: '(.*)\r\n'
        replace: '\1\n'
      with_items:
        - "hoge_crlf_to_lf.txt"
        - "hoge_lf_to_lf.txt"

    - name: LF to CRLF by replace
      replace:
        dest: "{{ item }}"
        regexp: '(.*)[^\r]\n'
        replace: '\1\r\n'
      with_items:
        - "hoge_crlf_to_crlf.txt"
        - "hoge_lf_to_crlf.txt"

やってることは、用意したファイルをコピーしてregexpでそれぞれCRLF -> LF およびその逆の変換を行なっているだけです。

結果は以下のとおり。

$ ansible-playbook test.yml 
 [WARNING]: Host file not found: /usr/local/etc/ansible/hosts

 [WARNING]: provided hosts list is empty, only localhost is available


PLAY [127.0.0.1] ***************************************************************

TASK [setup] *******************************************************************
ok: [127.0.0.1]

TASK [copy] ********************************************************************
changed: [127.0.0.1] => (item={u'dest': u'./hoge_crlf_to_lf.txt', u'src': u'org_crlf.txt'})
changed: [127.0.0.1] => (item={u'dest': u'./hoge_crlf_to_crlf.txt', u'src': u'org_crlf.txt'})
changed: [127.0.0.1] => (item={u'dest': u'./hoge_lf_to_lf.txt', u'src': u'org_lf.txt'})
changed: [127.0.0.1] => (item={u'dest': u'./hoge_lf_to_crlf.txt', u'src': u'org_lf.txt'})

TASK [CRLF to LF by replace] ***************************************************
changed: [127.0.0.1] => (item=hoge_crlf_to_lf.txt)
ok: [127.0.0.1] => (item=hoge_lf_to_lf.txt)

TASK [LF to CRLF by replace] ***************************************************
ok: [127.0.0.1] => (item=hoge_crlf_to_crlf.txt)
changed: [127.0.0.1] => (item=hoge_lf_to_crlf.txt)

PLAY RECAP *********************************************************************
127.0.0.1                  : ok=4    changed=3    unreachable=0    failed=0   

$ file hoge_*
hoge_crlf_to_crlf.txt: ASCII text, with CRLF line terminators
hoge_crlf_to_lf.txt:   ASCII text
hoge_lf_to_crlf.txt:   ASCII text, with CRLF line terminators
hoge_lf_to_lf.txt:     ASCII text

というわけでめでたくreplaceモジュールで改行コードの変換ができたようです。
ターゲットマシンがwindowsになった時にregexpに指定している'\n'がLFとして解釈されるのか、CRLFとして解釈されるのか気にはなりますが、ちょっと今時間が無いのでここで一旦終了します。
もし知ってる方いたら教えてもらえると助かります。

mac 上で vagrant + ansibleの環境構築

前回は、ホストマシンとしてWindows10を使った環境を作りましたが、そろそろLinux環境をゲストにしたものも必要になってきたのでサクっと作ってみました。

hpcmemo.hatenablog.com


既に入っているものもありますが、必要なソフトをbrewでインストールします。

> brew install Caskroom/cask/vagrant Caskroom/cask/vagrant-manager vagrant-completion \
                        Caskroom/cask/virtualbox Caskroom/cask/virtualbox-extension-pack ansible

今回はCentOS7で環境を作る必要があったので、こちらの記載を参考にvagrant initします。
Vagrant box centos/7 | Atlas by HashiCorp

> vagrant init centos/7

Vagrantfileにはとりあえずvirtualboxのメモリ設定だけ追加して、あとは仮に"site.yml"というplaybookの名前を指定しておきます。

$ cat Vagrantfile 
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.ssh.insert_key = false
  config.vm.provider "virtualbox" do |vb|
    vb.gui = false
    vb.memory = "4096"
  end
  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "./site.yml"
  end
end

最後にこのsite.ymlを作っていきます。といっても今回は単純な開発環境なので、こんな感じでyumを使っていくつかのパッケージを入れるだけの簡単なplaybookです。

$ cat site.yml 
- hosts: all
  tasks:
  - name: install basic tools for build C/C++/Fortran program
    become: yes
    yum:
      name: "{{item}}"
      state: latest
      update_cache: True
    with_items:
      - cmake
      - autoconf
      - automake
      - git
      - gcc.x86_64
      - gcc-c++.x86_64
      - gcc-gfortran.x86_64

ターゲット環境が毎回微妙に変わるので*1この辺のツールをインストールするところはroleにして再利用できるようにしておくと大変便利そうです(でもやってない)

*1:CentOS or RHELのバージョンが 6だったり5だったり、たまにUbuntuの時もあるけど

vagrant で modernIE

「せっかくだから、俺はこの銀の弁当箱を選ぶぜ!」くらいの勢いでMac miniを導入した私ですが、初っ端からwindows環境のお客様が続いています・・・
MSDNを導入するには予算オーバーだし、Macを買ってそうそうにwindowsのパッケージを買うのも負けた感があるので、modern IEで配ってるVMを使ってテスト環境を作るのが一番手っ取り早いんですが*1、ちょっと前まではvagrantから使うには一手間必要でした。

Setup modern.ie vagrant boxes · GitHub

が、いつの間にかMicrosoftからvagrantの形式でダウンロードできるようになっていたようです。

developer.microsoft.com

"Virtual Machine"のドロップダウンリストから必要なブラウザ&OSの組み合わせを選び、select platformの方のドロップダウンリストから"Vagrant"を選んで、下にある"Download Zip"ボタンを押すとVMをダウンロードすることができます。ただし、帯域制限しているのかうちの環境のせいかは不明ですが、1〜2MB/sec程度の転送レートになっちゃうので、ダウンロードするのに1時間くらいはかかります。*2


ひととおり、ダウンロードしてzipファイルを解凍するとこんな感じになります。

$ ls -s1
total 103168888
5017546388 IE10 - Win7.box
5017546668 IE10.Win7.Vagrant.zip
7378661428 IE11 - Win81.box
7378661710 IE11.Win81.Vagrant.zip
4496872696 IE8 - Win7.box
4496872974 IE8.Win7.Vagrant.zip
4800376728 IE9 - Win7.box
4800377006 IE9.Win7.Vagrant.zip
4717767002 MSEdge.Win10_RS1.Vagrant.zip
4717766724 dev-msedge.box

圧縮の意味が無いのはお約束 :p


とりあえずMS Edge+Win10のものを起動してみましょう。
最初にbox addコマンドでboxを追加しておきます。

 vagrant box add MSEdgeWin10 ./dev-msedge.box 
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'MSEdgeWin10' (v0) for provider: 
    box: Unpacking necessary files from: file:///Users/sogo/modernIE/dev-msedge.box
==> box: Successfully added box 'MSEdgeWin10' (v0) for 'virtualbox'!

続いて、適当なディレクトリを作成してvagrant initでVagrantfileを作成します。

$ mkdir test
$ cd test
$ vagrant box list
MSEdgeWin10 (virtualbox, 0)
$ vagrant init MSEdgeWin10
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

生成されたVagrantfileを編集して、中ほどにあるGUIの設定とメモリの設定を変更し、vramの設定を追加しておきます。
*3

config.vm.provider "virtualbox" do |vb|
  # Display the VirtualBox GUI when booting the machine
  vb.gui = true
  # Customize the amount of memory on the VM:
  vb.memory = "8192"
  vb.customize ["modifyvm", :id, "--vram", "256"]
end

でもってvagrant upするとvirtual boxのGUI画面が立ちあがって、そっちでWindows10が起動されます。
f:id:n_so5:20170113162619p:plain
コンソール側ではこんな感じで、延々とsshでのアクセスをしようとして失敗しタイムアウトしていますが、GUI使う分には問題無いです。気になる人は"config.vm.boot_timeout=5"とか適当に短いタイムアウト設定をVagrantfileに追加しておけば、コンソール側の処理も早く終わります。

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'MSEdgeWin10'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: WORK_default_1484292217879_22020
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
Timed out while waiting for the machine to boot. This means that
Vagrant was unable to communicate with the guest machine within
the configured ("config.vm.boot_timeout" value) time period.

If you look above, you should be able to see the error(s) that
Vagrant had when attempting to connect to the machine. These errors
are usually good hints as to what may be wrong.

If you're using a custom box, make sure that networking is properly
working and you're able to connect to the machine. It is a common
problem that networking isn't setup properly in these boxes.
Verify that authentication configurations are also setup properly,
as well.

If the box appears to be booting properly, you may want to increase
the timeout ("config.vm.boot_timeout") value.

しかし、実はこのwindowsゲスト内では、sshdが上がっているようでコマンドプロンプトを開いてlocalhostsshすると入れます。
f:id:n_so5:20170113225238p:plain
せっかく用意してくれてるなら、使わないと申し訳ないので一旦vagrant haltしてVagrantfileに以下の設定を追加しましょう。

config.vm.guest = :windows
config.ssh.username = "IEUser"
config.ssh.password = "Passw0rd!"

vm.questの設定はsshの設定とは直接関係ありませんが、この設定を入れておかないとログインしてsudoしようとして次のようなエラーを吐いてこけます。

==> default: Mounting shared folders...
    default: /vagrant => /Users/n_so5/Google Drive
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

mkdir -p /vagrant

Stdout from the command:



Stderr from the command:

sh: sudo: command not found

synced folderの設定くらいなら、使わなければ大丈夫なんですが、vagrant haltした時にはsudo shutdown -hしようとしてこけるので致命的です・・・

でもって、この設定を入れてvagrant upすると

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: IEUser
    default: SSH auth method: password
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
    default: The guest additions on this VM do not match the installed version of
    default: VirtualBox! In most cases this is fine, but in rare cases it can
    default: prevent things such as shared folders from working properly. If you see
    default: shared folder errors, please make sure the guest additions within the
    default: virtual machine match the version of VirtualBox you have installed on
    default: your host and reload your VM.
    default: 
    default: Guest Additions Version: 5.0.20
    default: VirtualBox Version: 5.1
==> default: Mounting shared folders...
    default: /vagrant => /Users/n_so5/Google Drive
==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision`
==> default: flag to force provisioning. Provisioners marked to run always will still run.


最終的にできあがったVagrantfileはこんな感じになってます。

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "MSEdgeWin10"
  config.vm.guest = :windows

  config.ssh.username = "IEUser"
  config.ssh.password = "Passw0rd!"

  config.vm.provider "virtualbox" do |vb|
    vb.gui = true
    vb.memory = "8192"
    vb.customize ["modifyvm", :id, "--vram", "256"]
  end
end


ん、winrm? 何それ美味しいの?

*1:と思ってたけどAzureにもwindows7/8.1がテスト環境として用意されてるんですね。こっちでも良かったかもしれん・・・

*2:複数のVMを並行してダウンロードしてもこの転送レートになるので使う可能性があるなら全部ダウンロードしておいても良いかもしれません。

*3:vramの設定を入れておかないと、ゲストOSの画面をfull screenにした時に文句を言われます。

コンパイラ製品のコミュニティエディション

MSがVisual StudioのComunity editionをリリースしてはや3年(くらいだっけ?)が経ちますが、同じようなノリでIntelとPGIもCommunity editionを出してたようです。*1


MSのも合わせてとりあえずリンクを置いときます。
www.visualstudio.com

www.softek.co.jp

Qualify for Free Software | Intel® Software


3社とも通常の商用版からサポート等を無くしたもののようですが、それぞれ微妙に条件や動作環境が違っていて

MS
Windows版のみ、学生、個人、非営利団体、中小企業のみ利用可
PGI
Linux版/Mac版のみ(MAC版はGPGPU関連機能無し)、利用者の制限は無いがリリースから1年間のみ有効*2
Intel
Windows/Linux/Mac版のみ、学生、教員、OSS貢献者のみ利用可(ただしOSS貢献者はLinux版のみ)

となっています。

MSに関してはFortranコンパイラが無いのも一部の人には重要な違いかもしれません:p
あと、Intelに関してはコンパイラに付属しているいつものライブラリ(TBB/IPP/MKL)とData Analytics Acceralation Library*3は対象者の制限無しに公開されています。

software.intel.com

WindowsならVS community、LinuxMacならPGIコンパイラをインストールして、Intelのライブラリを呼び出すのが一番制約が少なそうですね。
PGIコンパイラに関しては並列デバッガ(PGDBG)*4も含まれてるようなので、これがうまく使えれば開発が楽になりますね。


ーーーー
2017/04/09 リンクのミスを修正し、Intelコンパイラのページへのリンクが見え難くなっていたのでPGIと順番を入れ変えました。

*1:去年の秋ごろには見かけたような気がするけど、twitterでつぶやいただけでblogでは放置してたみたいで・・・

*2:Sharp Zaurusの開発環境を思いだした

*3:DAALと略すのかな?

*4:使ったことないけど・・・