質問編集履歴

3

タイトル変更

2019/03/22 20:46

投稿

nonshi
nonshi

スコア17

test CHANGED
@@ -1 +1 @@
1
- pythonコードをC++に埋め込みたい
1
+ pythonコードをC++に埋め込みたい(cythonを使って)
test CHANGED
File without changes

2

大幅な質問変更

2019/03/22 20:46

投稿

nonshi
nonshi

スコア17

test CHANGED
File without changes
test CHANGED
@@ -10,17 +10,11 @@
10
10
 
11
11
  では、本題へ
12
12
 
13
- 1.
14
-
15
- Pythonで書いコードをC++に埋め込みた
13
+ 実現したいことは
16
-
17
- 2.
18
-
19
- トスピードは100ms以内またはそれに近い速度を出したい。
20
14
 
21
15
 
22
16
 
23
- 2つ満たすコードを実現したいです。
17
+ Pythonで書いたコードをC++に埋め込みたいで、cython使ってpythonコードからcのコード生み出したいです。
24
18
 
25
19
  ### C++に埋め込みたいPythonコード
26
20
 
@@ -64,137 +58,133 @@
64
58
 
65
59
  ```
66
60
 
67
- ### 現在実現できている方法
61
+ ### cytest.pyx
68
62
 
63
+
64
+
65
+ joblib-ver-
66
+
67
+ ```pyx
68
+
69
+ from sklearn.externals import joblib
70
+
71
+ from libc.stdio cimport printf
72
+
73
+ cdef public struct Point:
74
+
75
+ double x
76
+
77
+ double y
78
+
79
+
80
+
81
+ cdef public Point func(Point a,Point b):
82
+
83
+ cdef Point b
84
+
69
- python.hを使ったC++からPython関数を呼ぶコード(これに関しては500msかかってしまい没)
85
+ model = joblib.load('model.joblib')
86
+
87
+ X_test = [[a.x,b.y]]
88
+
89
+ b = model.predict(X_test)
90
+
91
+ printf("b=%f\n",b)
92
+
93
+ return b
70
94
 
71
95
  ```
72
96
 
97
+ pickle-ver
98
+
99
+ ```pyx
100
+
101
+ from libc.stdio cimport printf
102
+
103
+ import pickle
104
+
105
+ cdef public struct Point:
106
+
107
+ double x
108
+
109
+ double y
110
+
111
+
112
+
113
+ cdef public Point func(Point x1,Point y1):
114
+
115
+ cdef Point b
116
+
117
+ f = open("model.pkl", "rb")
118
+
119
+ model = pickle.load(f)
120
+
121
+ X_test = [[x1.x,y1.y]]
122
+
123
+ b = model.predict(X_test)
124
+
125
+ return b
126
+
127
+ ```
128
+
129
+ ###setup.py
130
+
131
+ ```python
132
+
133
+ from distutils.core import setup
134
+
135
+ from Cython.Build import cythonize
136
+
137
+
138
+
139
+ setup(ext_modules=cythonize("cytest.pyx"))
140
+
141
+ ```
142
+
143
+
144
+
145
+ ###動かしたいC++プログラム
146
+
147
+ ```c++
148
+
149
+ #include <iostream>
150
+
73
- #include"pch.h"
151
+ #include<Python.h>
74
152
 
75
153
  #include<stdio.h>
76
154
 
77
- #include<Python.h>
155
+ #include "cytest.h"
78
-
79
- #include<string>
80
-
81
- #include<iostream>
82
-
83
- #include <chrono>
84
-
85
- using namespace std;
86
156
 
87
157
 
88
158
 
89
159
  int main() {
90
160
 
91
- chrono::system_clock::time_point start, end; // 型は auto で可
92
-
93
- start = chrono::system_clock::now(); // 計測開始時間
94
-
95
-
96
-
97
- PyObject *pName, *pModule, *pTmp, *pFunc;
98
-
99
- int res_data;
100
-
101
- int x = 345;
102
-
103
- int y = 781;
104
-
105
-
106
-
107
- //最初に必ず入れる
108
-
109
161
  Py_Initialize();
110
162
 
163
+ struct Point a;
111
164
 
165
+ struct Point b;
112
166
 
113
- //カレントディレクトリを探す範囲にいれる-------------------------
167
+ a.x = 0.2346;
114
168
 
115
- PyObject *sys = PyImport_ImportModule("sys");
169
+ b.y = 0.0324;
116
170
 
117
- PyObject *path = PyObject_GetAttrString(sys, "path");
171
+ struct Point b = func(a, b);
118
172
 
119
- PyList_Append(path, PyUnicode_DecodeFSDefault("."));
120
-
121
- //---------------------------------------------------------------
122
-
123
-
124
-
125
- //探すファイルをしてい-------------------------------------------
126
-
127
- pName = PyUnicode_DecodeFSDefault("a");
128
-
129
- pModule = PyImport_Import(pName);
130
-
131
- Py_DECREF(pName);
132
-
133
- //---------------------------------------------------------------
134
-
135
-
136
-
137
- //タプルの作成 -----------------------------------------------
138
-
139
- PyObject * pArgs = PyTuple_New(2);
140
-
141
- PyObject * pValue1 = PyFloat_FromDouble(x);
142
-
143
- PyObject * pValue2 = PyFloat_FromDouble(y);
144
-
145
- PyTuple_SetItem(pArgs, 0, pValue1);
146
-
147
- PyTuple_SetItem(pArgs, 1, pValue2);
148
-
149
- //---------------------------------------------------------------
150
-
151
-
152
-
153
- if (pModule != NULL) {
154
-
155
-
156
-
157
- //pFuncに今回呼び出す関数を設定する(今回はfunc)
158
-
159
- pFunc = PyObject_GetAttrString(pModule, "func");
160
-
161
-
162
-
163
- //pFuncを引数を与える(pArgsはタプルでなければならない)
164
-
165
- pTmp = PyObject_CallObject(pFunc, pArgs);
166
-
167
-
168
-
169
- //関数を実行 d:double型を受け取る
170
-
171
- PyArg_Parse(pTmp, "i", &res_data);
172
-
173
- printf("%i\n", res_data);
173
+ printf("b=%f\n", b);
174
-
175
- }
176
-
177
- //最後に必ず入れる
178
174
 
179
175
  Py_Finalize();
180
-
181
- // 処理
182
-
183
- end = chrono::system_clock::now(); // 計測終了時間
184
-
185
- double elapsed = chrono::duration_cast<chrono::milliseconds>(end - start).count(); //処理に要した時間をミリ秒に変換
186
-
187
- cout << elapsed << endl;
188
-
189
-
190
-
191
- return 0;
192
176
 
193
177
  }
194
178
 
195
179
  ```
196
180
 
181
+ ###現在詰まっているところ
197
182
 
183
+ ![イメージ説明](a55128c14bae7949684dfd045d7854b3.png)
184
+
185
+ python setup.py build_ext --inplaceを実行すると、
186
+
187
+ となっておりpickleをimportすることによってできるpickle.loadでコンパイルできないよって言われている。(おそらく)
198
188
 
199
189
  ### 補足情報(FW/ツールのバージョンなど)
200
190
 
@@ -205,3 +195,5 @@
205
195
  python3.6.8
206
196
 
207
197
  model.joblib(107KB)
198
+
199
+ model.pkl(502KB)

1

pickle-verーの追加

2019/03/22 20:44

投稿

nonshi
nonshi

スコア17

test CHANGED
File without changes
test CHANGED
@@ -42,6 +42,28 @@
42
42
 
43
43
  ```
44
44
 
45
+ 一応前回のpickle-ver-
46
+
47
+ ```python
48
+
49
+ import pickle
50
+
51
+ #保存しているpklファイルを読み込む
52
+
53
+ with open("model.pkl", "rb") as f:
54
+
55
+ model = pickle.load(f)
56
+
57
+ #ここで予測したい値を入れる
58
+
59
+ X_test = [[0.0401541,0.155155]]
60
+
61
+ #予測結果を出す
62
+
63
+ print(model.predict(X_test))
64
+
65
+ ```
66
+
45
67
  ### 現在実現できている方法
46
68
 
47
69
  python.hを使ったC++からPython関数を呼ぶコード(これに関しては500msかかってしまい没)