こんにちは!
ブレインズコンサルティングのゆるふわ担当の馬目です!
今回はゆるふわな記事として、Objective-CでPythonのモジュールを作成してみます。
PythonのモジュールをC/C++で記述できることは、公式ドキュメントでも説明されているのですが、
実はObjective-Cで記述したコードも、モジュールとしてビルドできます。
1. C や C++ による Python の拡張 — Python 3.7.2 ドキュメント
そこで、MacOSのAPIをPythonから叩いてみる手始めとして、
Metal APIを叩いて、デバイス名を取得するモジュールを作成してみようと思います。
TL;DR
環境
開発は以下の環境で行いました。
- 【端末】MacBook Pro (13-inch, 2016)
- 【OS】macOS Mojave 10.14.2
- 【Python】Python 3.7.1
- 【仮想環境構築】Pipenv
実装
主となる3つのファイルを作成していきます。
詳細はリポジトリを見ていただければ良いかなと思います。
Metal APIを叩くObjective-Cのコードを書く
device.mとして、以下の内容を記述。
#import <Metal/MTLDevice.h> NSString* getDeviceName() { NSArray<id<MTLDevice>> *availableDevices = MTLCopyAllDevices(); for(int i = 0; i < [availableDevices count]; i++) { NSLog(@"Device Index[%d]: %@", i, [availableDevices objectAtIndex: i].name); } return [availableDevices objectAtIndex: 0].name; }
上記のObjective-Cのコードを、Python側から利用できるようにラップする
deviceWrapper.mとして、以下の内容を記述。
#import <Foundation/NSString.h> #import "Python.h" extern NSString* getDeviceName(); PyObject* device_getDeviceName(PyObject* self) { NSString* deviceName = getDeviceName(); return Py_BuildValue("s", [deviceName UTF8String]); } static PyMethodDef deviceMethods[] = { {"getDeviceName", device_getDeviceName, METH_VARARGS}, {NULL}, }; static struct PyModuleDef devicemodule = { PyModuleDef_HEAD_INIT, "device", /* name of module */ "", /* module documentation, may be NULL */ -1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */ deviceMethods }; PyMODINIT_FUNC PyInit_device() { return PyModule_Create(&devicemodule); }
setup.pyを書く
setup.pyとして、以下の内容を記述。
"""Setup file.""" import os from setuptools import setup, Extension os.environ['LDFLAGS'] = '-framework Foundation' DEVICE_MODULE = Extension( 'pymetal.device', sources=[ 'pymetal/src/device.m', 'pymetal/deviceWrapper.m' ] ) setup( name='pymetal', author='Yukinori Manome', package_dir={ 'pymetal': 'pymetal', }, packages=[ 'pymetal', ], ext_modules=[DEVICE_MODULE], tests_require=['nose'], test_suite='nose.collector', platforms=['Mac OSX'] )
実行
できたらpython setup.py build
でビルドしてみましょう。
エラーが出なければ成功です!
そのまま使いたければpython setup.py install
でインストールできます。
使い方はリポジトリ内にexample
としてipynbを用意しているので、そちらを御覧ください。
まとめ
- Objective-Cでコードを書く
Python.h
をインポートして、上記のコードをラップしたコードを書く- C/C++の場合と同じ様に
setup.py
を書く
終わりに
楽しんでいただけたでしょうか。
これでMacOSのAPIをPythonから利用できるようになりましたので、
MacOS用のGPUを用いた数値計算ライブラリなんかを作っていけたら良いなぁと思っています。
以上、ゆるふわ担当の馬目でした!