ATIDLAS's python wrapper is now stand-alone

This commit is contained in:
Philippe Tillet
2014-10-15 04:24:25 -04:00
parent f91d3b422a
commit 30089b7fa6
13 changed files with 119 additions and 131 deletions

View File

@@ -10,9 +10,11 @@ find_package(ViennaCL QUIET REQUIRED)
include_directories(${VIENNACL_INCLUDE_DIRS}) include_directories(${VIENNACL_INCLUDE_DIRS})
find_package(OpenCL QUIET REQUIRED) find_package(OpenCL QUIET REQUIRED)
include_directories(${OPENCL_INCLUDE_DIRS})
include_directories(${OPENCL_INCLUDE_DIRS})
include_directories(${PROJECT_SOURCE_DIR}) include_directories(${PROJECT_SOURCE_DIR})
INCLUDE(CTest) INCLUDE(CTest)
add_subdirectory(tests) add_subdirectory(tests)
add_subdirectory(python)

View File

@@ -12,6 +12,7 @@
#include "viennacl/ocl/forwards.h" #include "viennacl/ocl/forwards.h"
#include "viennacl/scheduler/forwards.h" #include "viennacl/scheduler/forwards.h"
#include "viennacl/backend/mem_handle.hpp" #include "viennacl/backend/mem_handle.hpp"
#include "viennacl/device_specific/forwards.h"
namespace atidlas namespace atidlas
{ {
@@ -225,34 +226,7 @@ inline tools::shared_ptr<symbolic_binder> make_binder(binding_policy_t policy)
template<char C> template<char C>
struct char_to_type{ }; struct char_to_type{ };
class statements_container typedef viennacl::device_specific::statements_container statements_container;
{
public:
typedef std::list<viennacl::scheduler::statement> data_type;
enum order_type { SEQUENTIAL, INDEPENDENT };
statements_container(data_type const & data, order_type order) : data_(data), order_(order)
{ }
statements_container(viennacl::scheduler::statement const & s0) : order_(INDEPENDENT)
{
data_.push_back(s0);
}
statements_container(viennacl::scheduler::statement const & s0, viennacl::scheduler::statement const & s1, order_type order) : order_(order)
{
data_.push_back(s0);
data_.push_back(s1);
}
std::list<viennacl::scheduler::statement> const & data() const { return data_; }
order_type order() const { return order_; }
private:
std::list<viennacl::scheduler::statement> data_;
order_type order_;
};
} }
#endif #endif

View File

@@ -5,6 +5,7 @@
#include <vector> #include <vector>
#include "viennacl/scheduler/forwards.h" #include "viennacl/scheduler/forwards.h"
#include "viennacl/matrix_def.hpp" #include "viennacl/matrix_def.hpp"
#include "viennacl/matrix_proxy.hpp" #include "viennacl/matrix_proxy.hpp"
#include "viennacl/forwards.h" #include "viennacl/forwards.h"

18
python/CMakeLists.txt Normal file
View File

@@ -0,0 +1,18 @@
find_program(PYTHON "python")
if (PYTHON)
set(SETUP_PY_IN "${CMAKE_CURRENT_SOURCE_DIR}/setup.py")
set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py")
set(DEPS "${CMAKE_CURRENT_SOURCE_DIR}/pyatidlas/__init__.py")
set(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/build/timestamp")
configure_file(${SETUP_PY_IN} ${SETUP_PY})
add_custom_command(OUTPUT ${OUTPUT}
COMMAND ${PYTHON} ${SETUP_PY} build
COMMAND ${CMAKE_COMMAND} -E touch ${OUTPUT}
DEPENDS ${DEPS})
add_custom_target(pyatidlas ALL DEPENDS ${OUTPUT})
install(CODE "execute_process(COMMAND ${PYTHON} ${SETUP_PY} install)")
endif()

View File

@@ -4,38 +4,39 @@ import argparse
import itertools import itertools
import os import os
from configobj import ConfigObj
from numpy import random
import pyopencl as cl import pyopencl as cl
import pyviennacl as vcl import pyviennacl as vcl
from pyviennacl import backend, opencl, atidlas import pyatidlas as atd
from dataset import generate_dataset
from model import train_model
import tools import tools
import optimize import optimize
import sys import sys
from configobj import ConfigObj
from numpy import random
from dataset import generate_dataset
from model import train_model
DATATYPES = { 'single' : vcl.float32, DATATYPES = { 'single' : vcl.float32,
'double' : vcl.float64 } 'double' : vcl.float64 }
TYPES = { 'vector-axpy': {'template':vcl.atidlas.VectorAxpyTemplate, TYPES = { 'vector-axpy': {'template':atd.VectorAxpyTemplate,
'perf-index':lambda x: 3*x[0]*x[1][0]/x[2]*1e-9, 'perf-index':lambda x: 3*x[0]*x[1][0]/x[2]*1e-9,
'perf-measure':'GB/s'}, 'perf-measure':'GB/s'},
'matrix-axpy': {'template':vcl.atidlas.MatrixAxpyTemplate, 'matrix-axpy': {'template':atd.MatrixAxpyTemplate,
'perf-index':lambda x: 3*x[0]*x[1][0]*x[1][1]/x[2]*1e-9, 'perf-index':lambda x: 3*x[0]*x[1][0]*x[1][1]/x[2]*1e-9,
'perf-measure':'GB/s'}, 'perf-measure':'GB/s'},
'reduction': {'template':vcl.atidlas.ReductionTemplate, 'reduction': {'template':atd.ReductionTemplate,
'perf-index':lambda x: 2*x[0]*x[1][0]/x[2]*1e-9, 'perf-index':lambda x: 2*x[0]*x[1][0]/x[2]*1e-9,
'perf-measure':'GB/s'}, 'perf-measure':'GB/s'},
'row-wise-reduction': {'template':vcl.atidlas.RowWiseReductionTemplate, 'row-wise-reduction': {'template':atd.RowWiseReductionTemplate,
'perf-index':lambda x: x[0]*x[1][0]*x[1][1]/x[2]*1e-9, 'perf-index':lambda x: x[0]*x[1][0]*x[1][1]/x[2]*1e-9,
'perf-measure':'GB/s'}, 'perf-measure':'GB/s'},
'matrix-product': {'template':vcl.atidlas.MatrixProductTemplate, 'matrix-product': {'template': atd.MatrixProductTemplate,
'perf-index': lambda x: 2*x[1][0]*x[1][1]*x[1][2]/x[2]*1e-9, 'perf-index': lambda x: 2*x[1][0]*x[1][1]*x[1][2]/x[2]*1e-9,
'perf-measure': 'GFLOP/s'} } 'perf-measure': 'GFLOP/s'} }
@@ -149,7 +150,7 @@ def do_tuning(config_fname, viennacl_root):
if __name__ == "__main__": if __name__ == "__main__":
parser = argparse.ArgumentParser(); parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='action') subparsers = parser.add_subparsers(dest='action')
print_devices_parser = subparsers.add_parser('list-devices', help='list the devices available') print_devices_parser = subparsers.add_parser('list-devices', help='list the devices available')
tune_parser = subparsers.add_parser('tune', help='tune using a specific configuration file') tune_parser = subparsers.add_parser('tune', help='tune using a specific configuration file')
@@ -163,7 +164,7 @@ if __name__ == "__main__":
print("----------------") print("----------------")
devices = [d for platform in cl.get_platforms() for d in platform.get_devices()] devices = [d for platform in cl.get_platforms() for d in platform.get_devices()]
for (i, d) in enumerate(devices): for (i, d) in enumerate(devices):
print('Device', i, ':', tools.DEVICE_TYPE_PREFIX[d.type].upper() + ':', d.name, 'on', d.platform.name) print 'Device', i, '|', cl.device_type.to_string(d.type), '|', d.name, 'on', d.platform.name
print("----------------") print("----------------")
else: else:
print("------") print("------")

View File

@@ -3,7 +3,6 @@ import sys
import re import re
import random import random
import numpy as np import numpy as np
from pyviennacl.atidlas import FetchingPolicy
def resample(X, draw): def resample(X, draw):
Xtuples = [tuple(x) for x in X] Xtuples = [tuple(x) for x in X]

View File

@@ -2,10 +2,12 @@ import random
import time import time
import sys import sys
import tools import tools
import pyviennacl as vcl
import numpy as np
import copy import copy
import numpy as np
import pyatidlas as atd
import pyviennacl as vcl
from deap import algorithms from deap import algorithms
from deap import base from deap import base
from deap import creator from deap import creator
@@ -43,13 +45,13 @@ class GeneticOperators(object):
self.out = out self.out = out
self.genome_info = { self.genome_info = {
vcl.atidlas.VectorAxpyTemplate: [3,4,4,vcl.atidlas.FetchingPolicy], atd.VectorAxpyTemplate: [3,4,4,atd.FetchingPolicy],
vcl.atidlas.ReductionTemplate: [3,4,4,vcl.atidlas.FetchingPolicy], atd.ReductionTemplate: [3,4,4,atd.FetchingPolicy],
vcl.atidlas.MatrixAxpyTemplate: [3,3,3,3,3,vcl.atidlas.FetchingPolicy], atd.MatrixAxpyTemplate: [3,3,3,3,3,atd.FetchingPolicy],
vcl.atidlas.RowWiseReductionTemplate: [3,3,3,4,vcl.atidlas.FetchingPolicy], atd.RowWiseReductionTemplate: [3,3,3,4,atd.FetchingPolicy],
vcl.atidlas.MatrixProductTemplate: [3,3,3,3,3,3,3,vcl.atidlas.FetchingPolicy,vcl.atidlas.FetchingPolicy,3] atd.MatrixProductTemplate: [3,3,3,3,3,3,3,atd.FetchingPolicy,atd.FetchingPolicy,3]
}[TemplateType] }[TemplateType]
self.indpb = 1.0/sum([1 if x==vcl.atidlas.FetchingPolicy else x for x in self.genome_info]) self.indpb = 1.0/sum([1 if x==atd.FetchingPolicy else x for x in self.genome_info])
creator.create("FitnessMin", base.Fitness, weights=(-1.0,)) creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
creator.create("Individual", list, fitness=creator.FitnessMin) creator.create("Individual", list, fitness=creator.FitnessMin)
@@ -62,20 +64,20 @@ class GeneticOperators(object):
self.toolbox.register("select", deap_tools.selNSGA2) self.toolbox.register("select", deap_tools.selNSGA2)
def decode(self, genome): def decode(self, genome):
FetchingPolicy = vcl.atidlas.FetchingPolicy FetchingPolicy = atd.FetchingPolicy
fetch = [FetchingPolicy.FETCH_FROM_LOCAL, FetchingPolicy.FETCH_FROM_GLOBAL_CONTIGUOUS, FetchingPolicy.FETCH_FROM_GLOBAL_STRIDED] fetch = [FetchingPolicy.FETCH_FROM_LOCAL, FetchingPolicy.FETCH_FROM_GLOBAL_CONTIGUOUS, FetchingPolicy.FETCH_FROM_GLOBAL_STRIDED]
decode_element = lambda x:2**int(b_gray_to_bin(''.join(x)), 2) decode_element = lambda x:2**int(b_gray_to_bin(''.join(x)), 2)
result = [] result = []
offset = 0 offset = 0
for x in self.genome_info: for x in self.genome_info:
if x==vcl.atidlas.FetchingPolicy: if x==atd.FetchingPolicy:
result.append(fetch[genome[offset]]) result.append(fetch[genome[offset]])
offset = offset + 1 offset = offset + 1
else: else:
result.append(decode_element(genome[offset:offset+x])) result.append(decode_element(genome[offset:offset+x]))
offset = offset + x offset = offset + x
#GEMM peculiarities #GEMM peculiarities
if self.TemplateType==vcl.atidlas.MatrixProductTemplate: if self.TemplateType==atd.MatrixProductTemplate:
if FetchingPolicy.FETCH_FROM_LOCAL in result: if FetchingPolicy.FETCH_FROM_LOCAL in result:
lf1 = result[1]*result[3]/result[9] lf1 = result[1]*result[3]/result[9]
else: else:
@@ -90,14 +92,14 @@ class GeneticOperators(object):
while True: while True:
bincode = [] bincode = []
for x in self.genome_info: for x in self.genome_info:
if x==vcl.atidlas.FetchingPolicy: if x==atd.FetchingPolicy:
bincode = bincode + [random.randint(0,2)] bincode = bincode + [random.randint(0,2)]
else: else:
bincode = bincode + [str(random.randint(0,1)) for i in range(x)] bincode = bincode + [str(random.randint(0,1)) for i in range(x)]
parameters = self.decode(bincode) parameters = self.decode(bincode)
template = self.build_template(self.TemplateType.Parameters(*parameters)) template = self.build_template(self.TemplateType.Parameters(*parameters))
registers_usage = template.registers_usage(vcl.atidlas.StatementsTuple(self.statement))/4 registers_usage = template.registers_usage(vcl.pycore.StatementsTuple(self.statement))/4
lmem_usage = template.lmem_usage(vcl.atidlas.StatementsTuple(self.statement)) lmem_usage = template.lmem_usage(vcl.pycore.StatementsTuple(self.statement))
local_size = template.parameters.local_size_0*template.parameters.local_size_1 local_size = template.parameters.local_size_0*template.parameters.local_size_1
occupancy_record = tools.OccupancyRecord(self.device, local_size, lmem_usage, registers_usage) occupancy_record = tools.OccupancyRecord(self.device, local_size, lmem_usage, registers_usage)
if not tools.skip(template, self.statement, self.device): if not tools.skip(template, self.statement, self.device):

View File

@@ -7,7 +7,6 @@ import sys
import pyopencl as cl import pyopencl as cl
import pyviennacl as vcl import pyviennacl as vcl
from pyviennacl.atidlas import StatementsTuple
class PhysicalLimitsNV: class PhysicalLimitsNV:
def __init__(self, dev): def __init__(self, dev):
@@ -177,7 +176,7 @@ class OccupancyRecord:
def skip(template, statement, device): def skip(template, statement, device):
statements = StatementsTuple(statement) statements = vcl.pycore.StatementsTuple(statement)
registers_usage = template.registers_usage(statements)/4 registers_usage = template.registers_usage(statements)/4
lmem_usage = template.lmem_usage(statements) lmem_usage = template.lmem_usage(statements)
local_size = template.parameters.local_size_0*template.parameters.local_size_1 local_size = template.parameters.local_size_0*template.parameters.local_size_1
@@ -187,7 +186,7 @@ def skip(template, statement, device):
return False return False
def benchmark(template, statement, device): def benchmark(template, statement, device):
statements = StatementsTuple(statement) statements = vcl.pycore.StatementsTuple(statement)
registers_usage = template.registers_usage(statements)/4 registers_usage = template.registers_usage(statements)/4
lmem_usage = template.lmem_usage(statements) lmem_usage = template.lmem_usage(statements)
local_size = template.parameters.local_size_0*template.parameters.local_size_1 local_size = template.parameters.local_size_0*template.parameters.local_size_1

View File

@@ -0,0 +1 @@
from .pycore import *

View File

@@ -1,38 +1,11 @@
import abc, logging from . import _atidlas as _atd
from . import _viennacl as _v
from .pycore import Node, Statement
class OrderType(object):
def __init__(*args):
raise TypeError("This class is not supposed to be instantiated")
class SequentialOrder(OrderType):
vcl_order = _v.statements_tuple_order_type.SEQUENTIAL
class IndependentOrder(OrderType):
vcl_order = _v.statements_tuple_order_type.INDEPENDENT
class StatementsTuple(object): FetchingPolicy = _atd.fetching_policy_type
vcl_statements_tuple = None
def __init__(self, statements, order = SequentialOrder):
if not isinstance(statements, list):
statements = [statements]
def to_vcl_statement(s):
if isinstance(s, Node):
return Statement(s).vcl_statement
else:
return s.vcl_statement
vcl_statements = list(map(to_vcl_statement, statements))
self.order = order
self.vcl_tuple = _v.statements_tuple(vcl_statements, order.vcl_order)
FetchingPolicy = _v.fetching_policy_type
class TemplateBase(object): class TemplateBase(object):
Parameters = _v.template_base.parameters_type Parameters = _atd.template_base.parameters_type
def __init__(self): def __init__(self):
pass pass
@@ -61,48 +34,48 @@ class TemplateBase(object):
class VectorAxpyTemplate(TemplateBase): class VectorAxpyTemplate(TemplateBase):
Parameters = _v.vector_axpy_template.parameters_type Parameters = _atd.vector_axpy_template.parameters_type
def __init__(self, parameters): def __init__(self, parameters):
super(VectorAxpyTemplate, self).__init__() super(VectorAxpyTemplate, self).__init__()
self._vcl_template = _v.vector_axpy_template(parameters) self._vcl_template = _atd.vector_axpy_template(parameters)
class MatrixAxpyTemplate(TemplateBase): class MatrixAxpyTemplate(TemplateBase):
Parameters = _v.matrix_axpy_template.parameters_type Parameters = _atd.matrix_axpy_template.parameters_type
def __init__(self, parameters): def __init__(self, parameters):
super(MatrixAxpyTemplate, self).__init__() super(MatrixAxpyTemplate, self).__init__()
self._vcl_template = _v.matrix_axpy_template(parameters) self._vcl_template = _atd.matrix_axpy_template(parameters)
class ReductionTemplate(TemplateBase): class ReductionTemplate(TemplateBase):
Parameters = _v.reduction_template.parameters_type Parameters = _atd.reduction_template.parameters_type
def __init__(self, parameters): def __init__(self, parameters):
super(ReductionTemplate, self).__init__() super(ReductionTemplate, self).__init__()
self._vcl_template = _v.reduction_template(parameters) self._vcl_template = _atd.reduction_template(parameters)
class RowWiseReductionTemplate(TemplateBase): class RowWiseReductionTemplate(TemplateBase):
Parameters = _v.row_wise_reduction_template.parameters_type Parameters = _atd.row_wise_reduction_template.parameters_type
def __init__(self, parameters): def __init__(self, parameters):
super(RowWiseReductionTemplate, self).__init__() super(RowWiseReductionTemplate, self).__init__()
self._vcl_template = _v.row_wise_reduction_template(parameters) self._vcl_template = _atd.row_wise_reduction_template(parameters)
class MatrixProductTemplate(TemplateBase): class MatrixProductTemplate(TemplateBase):
Parameters = _v.matrix_product_template.parameters_type Parameters = _atd.matrix_product_template.parameters_type
def __init__(self, parameters, A_trans, B_trans): def __init__(self, parameters, A_trans, B_trans):
super(MatrixProductTemplate, self).__init__(); super(MatrixProductTemplate, self).__init__();
self._A_trans = A_trans self._A_trans = A_trans
self._B_trans = B_trans self._B_trans = B_trans
self._vcl_template = _v.matrix_product_template(parameters, A_trans, B_trans) self._vcl_template = _atd.matrix_product_template(parameters, A_trans, B_trans)
@property @property
def A_trans(self): def A_trans(self):

View File

@@ -38,13 +38,16 @@ def main():
return optlist return optlist
cvars = sysconfig.get_config_vars() cvars = sysconfig.get_config_vars()
cvars['OPT'] = str.join(' ', remove_prefixes(cvars['OPT'].split(), ['-g', '-O', '-Wstrict-prototypes', '-DNDEBUG'])) cvars['OPT'] = "-DNDEBUG -O3 " + str.join(' ', remove_prefixes(cvars['OPT'].split(), ['-g', '-O', '-Wstrict-prototypes', '-DNDEBUG']))
cvars["CFLAGS"] = cvars["BASECFLAGS"] + " " + cvars["OPT"]
DEFINES = [('VIENNACL_WITH_OPENCL','1')] DEFINES = [('VIENNACL_WITH_OPENCL',None), ('VIENNACL_WITH_OPENMP', None)]
INCLUDE_DIRS = [os.path.dirname(os.path.dirname(os.path.abspath(__file__)))] INCLUDE_DIRS = ['${PROJECT_SOURCE_DIR}','/home/philippe/Development/pyviennacl-dev/external/viennacl-dev']
LIBRARY_DIRS = ['/home/philippe/Development/pyviennacl-dev/build/lib.linux-x86_64-2.7/pyviennacl/']
setup( setup(
name="atidlas", name="pyatidlas",
package_dir={ '': '${CMAKE_CURRENT_SOURCE_DIR}' },
version=[], version=[],
description="Auto-tuned input-dependent linear algebra subroutines", description="Auto-tuned input-dependent linear algebra subroutines",
author='Philippe Tillet', author='Philippe Tillet',
@@ -72,20 +75,32 @@ def main():
'Topic :: Scientific/Engineering :: Machine Learning', 'Topic :: Scientific/Engineering :: Machine Learning',
], ],
packages=["atidlas"], packages=["pyatidlas"],
ext_package="atidlas", ext_package="pyatidlas",
ext_modules=[Extension( ext_modules=[Extension(
'_atidlas',[os.path.join("src", "_atidlas.cpp")], '_atidlas',[os.path.join('${CMAKE_CURRENT_SOURCE_DIR}', 'src', '_atidlas.cpp')],
extra_compile_args= [], extra_compile_args= [],
extra_link_args=[], extra_link_args=[],
define_macros=DEFINES, define_macros=DEFINES,
undef_macros=[], undef_macros=[],
include_dirs=INCLUDE_DIRS, include_dirs=INCLUDE_DIRS,
library_dirs=[], library_dirs=LIBRARY_DIRS,
libraries=['OpenCL'] libraries=['OpenCL', 'boost_python',':_viennacl.so']
)], )],
cmdclass={'build_ext': build_ext_subclass} cmdclass={'build_ext': build_ext_subclass}
) )
#from cx_Freeze import setup, Executable
#buildOptions = dict(packages = [], excludes = ['matplotlib'])
#base = 'Console'
#executables = [
# Executable('autotune/autotune.py', base=base)
#]
#setup(name='atidlas-tune',
# version = '1.0',
# description = 'Auto-tuning facility for ATIDLAS',
# options = dict(build_exe = buildOptions),
# executables = executables)
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@@ -1,8 +1,8 @@
#include <list> #include <list>
#include <boost/python.hpp> #include <boost/python.hpp>
#include "viennacl/scheduler/forwards.h" #include "viennacl/vector.hpp"
#include "viennacl/tools/shared_ptr.hpp" #include "viennacl/matrix.hpp"
#include "atidlas/templates/vector_axpy.hpp" #include "atidlas/templates/vector_axpy.hpp"
#include "atidlas/templates/matrix_axpy.hpp" #include "atidlas/templates/matrix_axpy.hpp"
@@ -85,7 +85,7 @@ void export_atidlas()
{ {
#define __PROP(name) __PROP_BASE(name, matrix_product_template) #define __PROP(name) __PROP_BASE(name, matrix_product_template)
WRAP_TEMPLATE(matrix_product_template, char, char); WRAP_TEMPLATE(matrix_product_template, char, char);
bp::scope b = WRAP_PARAMETERS(matrix_product_template, uint, uint, uint, uint, uint, uint, uint, atidlas::fetching_policy_type, atidlas::fetching_policy_type, uint, uint) WRAP_PARAMETERS(matrix_product_template, uint, uint, uint, uint, uint, uint, uint, atidlas::fetching_policy_type, atidlas::fetching_policy_type, uint, uint)
__PROP(kL) __PROP(mS) __PROP(kS) __PROP(nS) __PROP(kL) __PROP(mS) __PROP(kS) __PROP(nS)
__PROP(A_fetching_policy) __PROP(B_fetching_policy) __PROP(A_fetching_policy) __PROP(B_fetching_policy)
__PROP(local_fetch_0) __PROP(local_fetch_1) __PROP(local_fetch_0) __PROP(local_fetch_1)
@@ -94,9 +94,12 @@ void export_atidlas()
#undef __PROP #undef __PROP
} }
bp::enum_<atidlas::statements_container::order_type> }
("statements_tuple_order_type")
ENUM_VALUE(atidlas::statements_container, SEQUENTIAL) BOOST_PYTHON_MODULE(_atidlas)
ENUM_VALUE(atidlas::statements_container, INDEPENDENT) {
; // specify that this module is actually a package
bp::object package = bp::scope();
package.attr("__path__") = "_atidlas";
export_atidlas();
} }