linux pip install supporting & code reconstructing
This commit is contained in:
Родитель
e5bd34c91f
Коммит
185b871072
|
@ -1,4 +0,0 @@
|
|||
.PHONY: test
|
||||
test:
|
||||
cd ./multiverso && python -m unittest test.TestMultiversoTables.test_array
|
||||
cd ./multiverso && python -m unittest test.TestMultiversoTables.test_matrix
|
|
@ -1,10 +1,12 @@
|
|||
|
||||
|
||||
# Requirements
|
||||
I presume you followed the [README](../../README.md) and have build multiverso successfully.
|
||||
|
||||
|
||||
# Run tests
|
||||
```
|
||||
make test
|
||||
nosetests
|
||||
```
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
# coding:utf8
|
||||
|
||||
from api import init, shutdown, barrier, workers_num, worker_id, server_id,\
|
||||
ArrayTableHandler, MatrixTableHandler
|
||||
from api import init, shutdown, barrier, workers_num, worker_id, server_id
|
||||
from tables import ArrayTableHandler, MatrixTableHandler
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
# coding:utf8
|
||||
|
||||
from ctypes import *
|
||||
import ctypes
|
||||
from utils import Loader
|
||||
import numpy as np
|
||||
|
||||
|
@ -11,8 +11,8 @@ mv_lib = Loader.get_lib()
|
|||
|
||||
def init(args=[]):
|
||||
n = len(args)
|
||||
args_type = c_char_p * n
|
||||
mv_lib.MV_Init(pointer(c_int(n)), args_type(*[c_char_p(arg) for arg in args]))
|
||||
args_type = ctypes.c_char_p * n
|
||||
mv_lib.MV_Init(ctypes.pointer(ctypes.c_int(n)), args_type(*[ctypes.c_char_p(arg) for arg in args]))
|
||||
|
||||
|
||||
def shutdown():
|
||||
|
@ -32,95 +32,4 @@ def worker_id():
|
|||
|
||||
|
||||
def server_id():
|
||||
return my_lib.MV_ServerId()
|
||||
|
||||
|
||||
class TableHandler(object):
|
||||
def __init__(self, size):
|
||||
raise NotImplementedError("You must implement the __init__ method.")
|
||||
|
||||
def get(self, size):
|
||||
raise NotImplementedError("You must implement the get method.")
|
||||
|
||||
def add(self, data):
|
||||
raise NotImplementedError("You must implement the add method.")
|
||||
|
||||
|
||||
# types
|
||||
C_FLOAT_P = POINTER(c_float)
|
||||
|
||||
|
||||
class ArrayTableHandler(TableHandler):
|
||||
def __init__(self, size):
|
||||
self._handler = c_void_p()
|
||||
self._size = size
|
||||
mv_lib.MV_NewArrayTable(size, byref(self._handler))
|
||||
|
||||
def get(self):
|
||||
'''
|
||||
Data type of return value is numpy.ndarray
|
||||
'''
|
||||
data = np.zeros((self._size, ), dtype=np.dtype("float32"))
|
||||
mv_lib.MV_GetArrayTable(self._handler, data.ctypes.data_as(C_FLOAT_P), self._size)
|
||||
return data
|
||||
|
||||
def add(self, data):
|
||||
'''
|
||||
Data type of `data` is numpy.ndarray
|
||||
'''
|
||||
if not isinstance(data, np.ndarray):
|
||||
data = np.array(data)
|
||||
assert(data.size == self._size)
|
||||
data = data.astype(np.float32)
|
||||
mv_lib.MV_AddArrayTable(self._handler, data.ctypes.data_as(C_FLOAT_P), self._size)
|
||||
|
||||
|
||||
class MatrixTableHandler(TableHandler):
|
||||
def __init__(self, num_row, num_col):
|
||||
self._handler = c_void_p()
|
||||
self._num_row = num_row
|
||||
self._num_col = num_col
|
||||
self._size = num_col * num_row
|
||||
mv_lib.MV_NewMatrixTable(num_row, num_col, byref(self._handler))
|
||||
|
||||
def get(self, row_ids=None):
|
||||
'''
|
||||
If row_ids is None, we will return all rows as numpy.narray , e.g.
|
||||
array([[1, 3], [3, 4]]). Otherwise we will return the data according
|
||||
to the row_ids
|
||||
'''
|
||||
if row_ids is None:
|
||||
data = np.zeros((self._num_row, self._num_col), dtype=np.dtype("float32"))
|
||||
mv_lib.MV_GetMatrixTableAll(self._handler, data.ctypes.data_as(C_FLOAT_P), self._size)
|
||||
return data
|
||||
else:
|
||||
row_ids_n = len(row_ids)
|
||||
int_array_type = c_int * row_ids_n
|
||||
data = np.zeros((row_ids_n, self._num_col), dtype=np.dtype("float32"))
|
||||
mv_lib.MV_GetMatrixTableByRows(self._handler, data.ctypes.data_as(C_FLOAT_P),
|
||||
row_ids_n * self._num_col,
|
||||
int_array_type(*row_ids), row_ids_n)
|
||||
return data
|
||||
|
||||
def add(self, data=None, row_ids=None):
|
||||
'''
|
||||
If row_ids is None, we will add all data, and the data
|
||||
should be a list, e.g. [1, 2, 3, ...]
|
||||
|
||||
Otherwise we will add the data according to the row_ids
|
||||
'''
|
||||
assert(data is not None)
|
||||
if not isinstance(data, np.ndarray):
|
||||
data = np.array(data)
|
||||
data = data.astype(np.float32)
|
||||
|
||||
if row_ids is None:
|
||||
assert(data.size == self._size)
|
||||
mv_lib.MV_AddMatrixTableAll(self._handler, data.ctypes.data_as(C_FLOAT_P), self._size)
|
||||
else:
|
||||
row_ids_n = len(row_ids)
|
||||
assert(data.size == row_ids_n * self._num_col)
|
||||
int_array_type = c_int * row_ids_n
|
||||
mv_lib.MV_AddMatrixTableByRows(self._handler, data.ctypes.data_as(C_FLOAT_P),
|
||||
row_ids_n * self._num_col,
|
||||
int_array_type(*row_ids), row_ids_n)
|
||||
return mv_lib.MV_ServerId()
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
#!/usr/bin/env python
|
||||
# coding:utf8
|
||||
|
||||
import ctypes
|
||||
from utils import Loader
|
||||
import numpy as np
|
||||
|
||||
|
||||
mv_lib = Loader.get_lib()
|
||||
|
||||
|
||||
class TableHandler(object):
|
||||
def __init__(self, size):
|
||||
raise NotImplementedError("You must implement the __init__ method.")
|
||||
|
||||
def get(self, size):
|
||||
raise NotImplementedError("You must implement the get method.")
|
||||
|
||||
def add(self, data):
|
||||
raise NotImplementedError("You must implement the add method.")
|
||||
|
||||
|
||||
# types
|
||||
C_FLOAT_P = ctypes.POINTER(ctypes.c_float)
|
||||
|
||||
|
||||
class ArrayTableHandler(TableHandler):
|
||||
def __init__(self, size):
|
||||
self._handler = ctypes.c_void_p()
|
||||
self._size = size
|
||||
mv_lib.MV_NewArrayTable(size, ctypes.byref(self._handler))
|
||||
|
||||
def get(self):
|
||||
'''
|
||||
Data type of return value is numpy.ndarray
|
||||
'''
|
||||
data = np.zeros((self._size, ), dtype=np.dtype("float32"))
|
||||
mv_lib.MV_GetArrayTable(self._handler, data.ctypes.data_as(C_FLOAT_P), self._size)
|
||||
return data
|
||||
|
||||
def add(self, data):
|
||||
'''
|
||||
Data type of `data` is numpy.ndarray
|
||||
'''
|
||||
if not isinstance(data, np.ndarray):
|
||||
data = np.array(data)
|
||||
assert(data.size == self._size)
|
||||
data = data.astype(np.float32)
|
||||
mv_lib.MV_AddArrayTable(self._handler, data.ctypes.data_as(C_FLOAT_P), self._size)
|
||||
|
||||
|
||||
class MatrixTableHandler(TableHandler):
|
||||
def __init__(self, num_row, num_col):
|
||||
self._handler = ctypes.c_void_p()
|
||||
self._num_row = num_row
|
||||
self._num_col = num_col
|
||||
self._size = num_col * num_row
|
||||
mv_lib.MV_NewMatrixTable(num_row, num_col, ctypes.byref(self._handler))
|
||||
|
||||
def get(self, row_ids=None):
|
||||
'''
|
||||
If row_ids is None, we will return all rows as numpy.narray , e.g.
|
||||
array([[1, 3], [3, 4]]). Otherwise we will return the data according
|
||||
to the row_ids
|
||||
'''
|
||||
if row_ids is None:
|
||||
data = np.zeros((self._num_row, self._num_col), dtype=np.dtype("float32"))
|
||||
mv_lib.MV_GetMatrixTableAll(self._handler, data.ctypes.data_as(C_FLOAT_P), self._size)
|
||||
return data
|
||||
else:
|
||||
row_ids_n = len(row_ids)
|
||||
int_array_type = ctypes.c_int * row_ids_n
|
||||
data = np.zeros((row_ids_n, self._num_col), dtype=np.dtype("float32"))
|
||||
mv_lib.MV_GetMatrixTableByRows(self._handler, data.ctypes.data_as(C_FLOAT_P),
|
||||
row_ids_n * self._num_col,
|
||||
int_array_type(*row_ids), row_ids_n)
|
||||
return data
|
||||
|
||||
def add(self, data=None, row_ids=None):
|
||||
'''
|
||||
If row_ids is None, we will add all data, and the data
|
||||
should be a list, e.g. [1, 2, 3, ...]
|
||||
|
||||
Otherwise we will add the data according to the row_ids
|
||||
'''
|
||||
assert(data is not None)
|
||||
if not isinstance(data, np.ndarray):
|
||||
data = np.array(data)
|
||||
data = data.astype(np.float32)
|
||||
|
||||
if row_ids is None:
|
||||
assert(data.size == self._size)
|
||||
mv_lib.MV_AddMatrixTableAll(self._handler, data.ctypes.data_as(C_FLOAT_P), self._size)
|
||||
else:
|
||||
row_ids_n = len(row_ids)
|
||||
assert(data.size == row_ids_n * self._num_col)
|
||||
int_array_type = ctypes.c_int * row_ids_n
|
||||
mv_lib.MV_AddMatrixTableByRows(self._handler, data.ctypes.data_as(C_FLOAT_P),
|
||||
row_ids_n * self._num_col,
|
||||
int_array_type(*row_ids), row_ids_n)
|
|
@ -1,14 +1,21 @@
|
|||
#!/usr/bin/env python
|
||||
# coding:utf8
|
||||
import api as mv
|
||||
import multiverso as mv
|
||||
import unittest
|
||||
|
||||
|
||||
def setUpModule():
|
||||
mv.init()
|
||||
|
||||
|
||||
def tearDownModule():
|
||||
mv.shutdown()
|
||||
|
||||
|
||||
class TestMultiversoTables(unittest.TestCase):
|
||||
'''
|
||||
Use the commands below to run test
|
||||
python -m unittest test.TestMultiversoTables.test_array
|
||||
python -m unittest test.TestMultiversoTables.test_matrix
|
||||
$ nosetests
|
||||
'''
|
||||
|
||||
def _test_array(self, size):
|
||||
|
@ -24,8 +31,12 @@ class TestMultiversoTables(unittest.TestCase):
|
|||
mv.barrier()
|
||||
|
||||
def test_small_array(self):
|
||||
# TODO : this is not supported by multiverso because of the size limited
|
||||
self._test_array(1)
|
||||
# TODO : this is not supported by multiverso because of the size
|
||||
# limited. Waiting for the solution of this issue
|
||||
# https://github.com/Microsoft/multiverso/issues/69
|
||||
|
||||
# self._test_array(1)
|
||||
pass
|
||||
|
||||
def test_array(self):
|
||||
self._test_array(10000)
|
||||
|
@ -57,8 +68,6 @@ class TestMultiversoTables(unittest.TestCase):
|
|||
expected = (row_ids[i] * num_col + j) * count * workers_num * 2
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def setUp(self):
|
||||
mv.init()
|
||||
|
||||
def tearDown(self):
|
||||
mv.shutdown()
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -4,8 +4,7 @@
|
|||
import ctypes
|
||||
import os
|
||||
|
||||
PROJECT_PATH = os.path.abspath(os.path.join(
|
||||
os.path.dirname(__file__), os.path.pardir, os.path.pardir, os.path.pardir))
|
||||
PACKAGE_PATH = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
class Loader(object):
|
||||
|
@ -16,7 +15,7 @@ class Loader(object):
|
|||
def load_lib(cls):
|
||||
# TODO: write some scripts load .so or .dll
|
||||
# TODO: adapt it for windows
|
||||
path = os.path.join(PROJECT_PATH,"build", "src", "libmultiverso.so")
|
||||
path = os.path.join(PACKAGE_PATH, "libmultiverso.so")
|
||||
return ctypes.cdll.LoadLibrary(path)
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
from setuptools import setup
|
||||
from setuptools.command.install import install
|
||||
import shutil
|
||||
import os
|
||||
|
||||
PACKAGE_PATH = os.path.abspath(os.path.dirname(__file__))
|
||||
PROJECT_PATH = os.path.abspath(os.path.join(PACKAGE_PATH, os.path.pardir, os.path.pardir))
|
||||
|
||||
|
||||
class mv_install(install):
|
||||
'''
|
||||
This customized command will place the multiverso.so to the right place.
|
||||
'''
|
||||
def run(self):
|
||||
# TODO: find better way to get the libmultiverso.so
|
||||
mv_so = os.path.join(PROJECT_PATH, "build", "src", "libmultiverso.so")
|
||||
if os.path.exists(mv_so):
|
||||
shutil.copy(mv_so, os.path.join(PACKAGE_PATH, "multiverso"))
|
||||
install.run(self)
|
||||
else:
|
||||
msg = "The libmultiverso.so(" + mv_so + ") can't be found, please"\
|
||||
" make sure you have followed the guide here"\
|
||||
"(https://github.com/Microsoft/multiverso/#build) and built"\
|
||||
"it successfully."
|
||||
print "\033[93m" + msg + '\033[0m'
|
||||
|
||||
|
||||
def readme():
|
||||
with open('README.md') as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
setup(name='multiverso-python',
|
||||
version='0.1',
|
||||
long_description=readme(),
|
||||
description="Multiverso is a parameter server framework for distributed"
|
||||
" machine learning. This package can leverage multiple machines and GPUs"
|
||||
" to speed up the python programs.",
|
||||
url='https://github.com/Microsoft/multiverso',
|
||||
author='Microsoft',
|
||||
license='MIT',
|
||||
packages=['examples.theano', 'examples.theano.lasagne', 'multiverso',
|
||||
'multiverso.theano_ext', 'multiverso.theano_ext.lasagne_ext'],
|
||||
install_requires=["theano", "lasagne"],
|
||||
cmdclass={"install": mv_install},
|
||||
package_dir={'multiverso': 'multiverso'},
|
||||
package_data={
|
||||
'multiverso': ['libmultiverso.so'],
|
||||
},
|
||||
include_package_data=True,
|
||||
zip_safe=False)
|
Загрузка…
Ссылка в новой задаче