BlankTar

about | blog | works | photo

gentooでGPU使ってchainerをやるべくopencv3とかnvidia-cuda-toolkitを入れなおしまくっていたところ、唐突にportageが仕事をしなくなりました。
どうも、f2pyとして起動しているっぽい?

こんな感じの症状。

$ emerge
Usage:

1) To construct extension module sources:

      f2py [<options>] <fortran files> [[[only:]||[skip:]] \
                                        <fortran functions> ] \
                                       [: <fortran files> ...]

2) To compile fortran files and build extension modules:

      f2py -c [<options>, <build_flib options>, <extra options>] <fortran files>

3) To generate signature files:

      f2py -h <filename.pyf> ...< same options as in (1) >

Description: This program generates a Python C/API file (<modulename>module.c)
             that contains wrappers for given fortran functions so that they
             can be called from Python. With the -c option the corresponding
             extension modules are built.

Options:

  -- -- -- 中略 -- -- --

Version:     2
numpy Version: 1.11.1
Requires:    Python 2.3 or higher.
License:     NumPy license (see LICENSE.txt in the NumPy source code)
Copyright 1999 - 2011 Pearu Peterson all rights reserved.
http://cens.ioc.ee/projects/f2py2e/

よく分からないのですが、とりあえず、以下のようにすれば治るようです。

# /usr/lib/python-exec/python3.4/emerge --oneshot portage python-exec

emergeを起動出来なくなったら/usr/lib/python-exec/以下にあるやつを使えば良い、ということのようです。たぶん。

参考: Gentoo Forums :: View topic - Problem with emerge / python-exec

PyCon JP 2016に行ってきました。楽しかったです。そんなことはどうでもいいです。いやどうでもよくないですが。
色々なお話を聞いていたら、PEPを読みたくなりました。読みました。

Python3.6から、関数アノテーションに引き続いて(?)変数アノテーション(Variable Annotations)なるものが導入されるようです。
PEP526に詳細に書いてあるので、そちらを読んでいただけると宜しいかと思います。
この記事では大雑把に変数アノテーションとは何ぞやというお話を。

何が新しいのか

従来の型ヒント(PEP484あたり)では、変数に対するアノテーションはコメントの形を取って行なわれていました。

x = 10  # type: int
ys = [1, 2, 3]  # type: Iterable[int]

こんな感じ。

構文を追加しなくて良いから素敵ってことらしいんですが、なんか、ダサい。

同じ意味のことを、PEP526の変数アノテーションを使うと以下のように書けます。

x: int = 10
ys: Iterable[int] = [1, 2, 3]

かっこいい。

しかもこの構文だと、アノテーションだけ書いて値を定義しない、みたいなことが出来ます。

x: int
ys: Iterable[int]

x = 10
ys = [1, 2, 3]

アノテーションと代入を分けてみた感じ。
静的に変数を定義して使っているように見えますね。

分離して書けるようになったことで、if文で場合分けしたりして書くような場合にシンプルに記述出来るようになりました。

if check_A():
    a = get_A()  # type: int
else:
    a = 0  # type: int

b: int
if check_B():
    b = get_B()
else:
    b = 0

アノテーションを書くということの意味

関数アノテーションを書くと、関数のメンバ変数__annotations__というものの中にアノテーションの内容が保存されます。

>>> def f(x: int) -> str:
...     return 'hoge' * x
...
>>> f.__annotations__
{'x': < 'int'>, 'return': <class 'str'>}

こんな感じでアクセス出来ます。lintはこの情報にアクセスしているわけですね。

変数アノテーションの場合はどうなるかというと、そのまんま__annotations__というものの中に入ります。
この変数は名前空間毎(というよりモジュール毎?)に用意されます。

>>> x: int = 0
>>> __annotations__
{'x': <class 'int'>}

>>> y: str
>>> __annotations__
{'x': <class 'int'>, 'y': <class 'str'>}

なんとこの変数は普通に書き換え可能ですが、書き換えない方が良いような気がします。

関数アノテーションと同じく、変数アノテーションに記述する内容は何でも良いようです。
PEP526には以下のような例が載っています。(ちょっと変えてます)

>>> alice: 'well done' = 'A+'
>>> bob: 'what a shame' = 'F-'
>>> __annotations__
{'alice': 'well done', 'bob': 'what a shame'}

奇妙なことになっている気がしますが、まあこれはこれでアリらしいです。
なるべく型ヒントに使うことをお勧めするよ、みたいなことが書かれています。

アノテーションを書くと起こること

上記の通り、アノテーションの内容は__annotations__という名前のdictに入る、というのが変数アノテーションの趣旨でした。
というより、それ以上のことは何もしてくれない、というのが正しいようです。

>>> x: int
>>> x
Traceback (most recent call last):
  ...
NameError: name 'x' is not defined
>>> __annotations__
{'x': <class 'int'>}

変数アノテーションを書くと、__annotations__にアノテーションの内容が保存されます。
しかし、変数の宣言とか確保とかいう意味合いは全く無いので変数にアクセスすることは出来ません。

>>> x: int
{'x': <class 'int'>}

>>> x: str
>>> __annotations__
{'x': <class 'str'>}

アノテーションの内容は(文法上は)何の問題も無く上書きすることが出来ます。
エラーチェッカの挙動については「Static type checker may or may not warn about this.」らしいです。PEPとしては関与しませんよって感じ?
型ヒントの意味を考えると、やめておいた方が無難だと思います。

>>> __annotations__ = None
>>> x: int
Traceback (most recent call last):
  ...
TypeError: 'NoneType' object does not support item assignment

__annotations__変数に内容を入れる(__setitem__を呼ぶ)、というだけの挙動なので、そもそも入れられない型で上書きされてしまっているとエラーが発生します。

この性質を逆用して、以下のようにフックすることも可能です。

>>> class Test:
...     def __setitem__(self, k, v):
...         print('annotation:', k, v)
...
>>> __annotations__ == Test()
>>> a: int
annotation: a <class 'int'>

クラス変数とインスタンス変数

typingモジュールにClassVarなるものが追加されています。
これを使って、クラス変数とインスタンス変数を区別してヒンティング出来るらしいです。

import typing

class Greeter:
    greet: typing.ClassVar[str]
    name: str

    def __init__(self, name: str) -> None:
        self.name = name

    def say(self -> None:
        print(f'{self.greet} {self.name}')

if __name__ == '__main__':
    g = Greeter('world')
    g.greet = 'hello'
    g.say()

こんな感じで良い、らしいです。らしいのですが、mypyのリポジトリにまだプルリクがマージされてなかったりしてよく分かりません。試せません。
わくわくしながら待ちましょう。

結局変数アノテーションとは何なのか

全体として見てみると、あまり今まで定義されてきたアノテーションとあまり変らない感じです。
変数にアノテーションを付ける専用の構文が出来たことで見やすく書きやすくなった、ということみたい。

アノテーションや型ヒントを付けたところでやっぱり実行速度に影響することは無いし、やっぱり動的型付け言語のままらしいです。
漸進的型付けが本当に活きてくるのはもうちょっと周辺のツール群が充実してからかなぁ…。

私とASUSのX205TAとの戦いの始まりは去年の2月に遡ります。gentoo入れようとしては失敗し、Arch Linux入れてはドライバが足りず…。
そしてついに、その戦いに決着が付きました。

Remix OSなるOSがあります。
元Googleの開発者が作ったOSとかで、Androidベース…というか、デスクトップ版Androidみたいな代物です。
結構面白いので実機に入れてみようと思ってX205TAに入れたのですが、これがかなり良い。

簡単にですが、手順を記録しておきます。
なお、ここで行なっている手順は非常に荒っぽいです
正直言ってマトモな手順ではありません。自己責任でどうぞ。

RemixOSを起動するためのUSBメモリを用意する

Remix OSのダウンロードページから64bit向けのzipファイルをダウンロードしてきます。
展開するとISOとexeが入っているはずです。

付属してきたexeでISOファイルをUSBメモリに入れます。
USBメモリは8GB以上32GB以下のものにしてください。普通に使う分には32GB以下って制限は無いのですが、この記事の方法でインストールする場合は必ず守った方が良いと思います。

例によってX205TAのUEFIではこのままでは起動出来ないので、一度マウントしてブートローダを差し替えます。
/EFI/boot//EFI/RemixOS/の二つのディレクトリにあるbootia32.efix100ta用のもので置き換えます。

これで準備完了。

BIOS(UEFI)の準備

もしもまだBIOS設定に入るための準備をしていないのなら、windowsの高速起動を無効にする必要があります。
Shiftを押しながら再起動ボタンをクリックして、トラブルシューティング->詳細オプション->UEFIファームウェアの順に選択していきます。

BIOS画面に入ったら、AdvancedタブのUSB ConfigurationでUSB Controller SelectをEHCIにします。
それと、SecurityタブのSecure Boot ControlをDisabledにしてください。

USBブートする

作ったUSBメモリをX205TAに挿して、BIOS画面のSave & ExitタブのBoot OverrideってやつからUSBメモリを選んでUSBブートします。
GRUBの画面に入ったらGuest modeってやつで起動。Resident modeでも良いのですが、やたらと遅くなったりするのでお勧めしません。
ちょっと時間が掛かるかもしれないけれど、辛抱して起動を待つ。

最初の設定に入るので、そのへんは適当に。
ただし、Wi-Fiはスキップしないで設定してください。ターミナルアプリを入れるために必要です。

インストール

いよいよインストール作業です。
本来ならばGRUB画面でブートオプションを書き換えて起動するインストーラを使うのですが、試した限りではうまく行きませんでした。
普通のインストーラの使い方を詳細に書かれている記事がありましたので、参考までにどうぞ。

で、入らないからどうするかというと、ddコマンドを使ってUSBメモリの中身を丸ごと内蔵ストレージにコピーします。
無茶苦茶な方法ですが、良い感じに出来ました。

Termuxというアプリが入っているので、左下のスタートボタン的なところから探して起動します。
起動したら以下のような感じで。

$ su -
# dd if=/dev/block/sda of=/dev/block/mmcblk0 bs=8192 count=1048576

これでインストール(というかコピー)することが出来ます。
死ぬほど時間がかかりますが、辛抱強く見守ってあげてください。

なお、bsとかcountオプションについては8GBのUSBメモリを使用した場合を想定しています。
bsとcountを掛けた値がUSBメモリのサイズになるように設定してください。

ddコマンドが無事終われば、ひとまず起動出来る状態になっているはずです。
途中でフリーズしてしまった感じがしても、強制終了させて起動してみると案外行けたりするかも? 私の場合はそんな感じでした。

パーティションの拡張

私が今回インストールに使用したUSBメモリは8GBのものです。
8GBのUSBメモリを32GBのeMMCにddしたので、当然かなりのスペースが無駄になっています。
勿体無いので、パーティションを広げておきます。

失敗するとデータが消えてしまうので、/dev/block/mmcblk0p3の中身のバックアップをしておくことを強くお勧めします。

バックアップが終わったら、自動でマウントされているものをアンマウントしてください。

準備が出来たらさきほどと同じくTermuxを起動して、以下のようにして拡張を行ないます。

$ su -
# fdisk /dev/block/mmcblk0
Command ('m' for help): p
Disk /dev/block/mmcblk0: 31.2 GB, 31272730624 bytes
4 heads, 16 sectors/track, 954368 cylinders
Units = cylinders of 64 * 512 = 32768 bytes

			 Device Boot      Start         End      Blocks  Id System
/dev/block/mmcblk0p1              33       34304     1096704   c Win95 FAT32 (LBA)
Partition 1 does not end on cylinder boundary
/dev/block/mmcblk0p2   *       34305      198144     5242880   b Win95 FAT32
Partition 2 does not end on cylinder boundary
/dev/block/mmcblk0p3          198145      247296     1572864  83 Linux
Partition 3 does not end on cylinder boundary


Command ('m' for help): d
Partition (1 - 4): 3


Command ('m' for help): n
  e  extended
  p  primary partition(1-4)
p

Partition (1 - 4): 3

First cylinder (1 - 954368, default 1): 198145

Last cylinder or +size or +sizeM or +sizeK (198145 - 954368, default 954368):
Using default value 954368


Command ('m' for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table
fdisk: WARNING rereading partition table failed, kernel still uses old table: Device or resource busy

パーティション3のstartの位置をpコマンドで確認して、nコマンドで同じ場所に新しいパーティションを作っています。
間違えるとデータを読み出せなくなるので要注意。

リソースが使用中だとか文句を言われたので、素直に再起動してもう一度USBメモリから起動します。
やっぱりTermuxを開いて、以下のように。

$ su -
# e2fsck -f /dev/block/mmcblk0p3
# resize2fs /dev/block/mmcblk0p3

これでパーティションの拡張は完了です。

内蔵ストレージからの起動

シャットダウンしてUSBメモリを抜いて、もう一度起動します。
すると内蔵ストレージから起動する、はず。きっと。
初回起動は時間が掛かったりしますが、何度かやってるとそこそこ早くなる気がします。体感ですが。

ハードウェアの対応状況

Wi-Fiとディスプレイの輝度、バッテーの状態取得、Webカメラは問題なく動作します。
タッチパッドもほぼ完全に動作しますが、二本指でのタップが無いっぽいです。右下をクリックすれば問題無し。

キーボードのファンクションは確認出来た範囲で機内モード、ディスプレイ輝度、音量調整などが使えます。
機内モードはOS側の機内モードとは別らしく、解除がちょっと面倒臭いので注意。キーボードで解除してからOS側のWi-Fiをオンオフしないといけない。
あと、fn + F8で何故か音楽プレイヤーが立ち上がります。

キーボードから音量調整が行なえると書きましたが、肝心の音は出ないようです。
内蔵スピーカー、イヤホン、HDMIの全てがダメでした。無念。

HDMIの映像出力は出来ますが、解像度を調整する術がありません。
そもそもディスプレイの解像度を調整出来ないので、Androidの宿命のようです。
ドライバ的には対応しているようなので、RemixOSの今後に期待?

スリープ状態に入ることは出来ますが、映像は復帰出来ても高確率でキーボードもタッチパッドも反応しなくなります。
たまにキーボードは使えるようになりますが、タッチパッドは今のところ復帰出来たことがありません。
タイムアウトによる自動スリープに注意。設定変えといた方が良いかも。

Bluetoothは使えません。そもそも認識していないようです。

色々動いてない感じがしますが、この子にしては上出来です。随分動いてます。やったね。

[ << ] [ 1 ] [ 3 ] [ 5 ] [ >> ]