Compare commits

...
Sign in to create a new pull request.

2 commits

Author SHA1 Message Date
Siu Kwan Lam
ca192850ee Silent capsule memory logger. 2013-05-14 00:55:09 -05:00
Travis E. Oliphant
7a77be01cc Fix a few erros. Add an array type 2013-05-14 00:51:45 -05:00
7 changed files with 176 additions and 1 deletions

2
llvm_array/__init__.py Normal file
View file

@ -0,0 +1,2 @@
from __future__ import absolute_imports
from .array.py import *

144
llvm_array/array.py Normal file
View file

@ -0,0 +1,144 @@
# This should be moved to llvmpy
#
# There are different array kinds parameterized by eltype and nd
#
# Contiguous or Fortran
# struct {
# eltype *data;
# intp shape[nd];
# } contiguous_array(eltype, nd)
#
# struct {
# eltype *data;
# diminfo shape[nd];
# } strided_array(eltype, nd)
#
# struct {
# eltype *data;
# intp shape[nd];
# intp stride[nd];
# } strided_soa_array(eltype, nd)
#
# struct {
# intp dim;
# intp stride;
#} diminfo
#
import llvm.core as lc
from llvm.core import Type
import llvm_cbuilder.shortnames as C
CONTIGUOUS = 1 << 8
STRIDED = CONTIGUOUS + 1
STRIDED_SOA = CONTIGUOUS + 2
array_kinds = (CONTIGUOUS, STRIDED, STRIDED_SOA)
void_type = C.void
int_type = C.int
char_type = C.char
int16_type = C.int16
intp_type = C.intp
diminfo_type = Type.struct([intp_type, # shape
intp_type # stride
], name='diminfo')
# This is the way we define LLVM arrays.
def cont_array_type(nd, el_type=char_type, name=''):
terms = [Type.pointer(el_type), # data
Type.array(intp_type, nd) # shape
]
return Type.struct(terms, name=name)
def strided_array_type(nd, el_type=char_type, name=''):
terms = [Type.pointer(el_type), # data
Type.array(diminfo_type, nd) # diminfo
]
return Type.struct(terms, name=name)
def strided_soa_type(nd, el_type=char_type, name=''):
terms = [Type.pointer(el_type), # data
Type.array(intp_type, nd), # shape[nd]
Type.array(intp_type, nd) # strides[nd]
]
return Type.struct(terms, name=name)
def check_array(arrtyp):
if not isinstance(arrtyp, lc.StructType):
return None
if arrtyp.element_count not in [2, 3]:
return None
if not isinstance(arrtyp.elements[0], lc.PointerType) or \
not isinstance(arrtyp.elements[1], lc.ArrayType):
return None
data_type = arrtyp.elements[0].pointee
s1 = arrtyp.elements[1]
nd = s1.count
if arrtyp.element_count == 3:
if not isinstance(arrtyp.elements[2], lc.ArrayType):
return None
s2 = arrtyp.elements[2]
if s1.element != intp_type or s2.element != intp_type:
return None
if s1.count != s2.count:
return None
return STRIDED_SOA, nd, data_type
if s1.element == diminfo_type:
return STRIDED, nd, data_type
elif s1.element == intp_type:
return CONTIGUOUS, nd, data_type
else:
return None
def is_cont_array(arrtyp):
if not isinstance(arrtyp, lc.StructType):
return False
if arrtyp.element_count != 2 or \
not isinstance(arrtyp.elements[0], lc.PointerType) or \
not isinstance(arrtyp.elements[1], lc.ArrayType):
return False
if arrtyp.elements[1].element != intp_type:
return False
return True
def is_strided_array(arrtyp, kind=diminfo_type):
if not isinstance(arrtyp, lc.StructType):
return False
if arrtyp.element_count != 2 or \
not isinstance(arrtyp.elements[0], lc.PointerType) or \
not isinstance(arrtyp.elements[1], lc.ArrayType):
return False
if arrtyp.elements[1].element != kind:
return False
return True
def is_strided_soa_array(arrtyp):
if not isinstance(arrtyp, lc.StructType):
return False
if arrtyp.element_count != 3 or \
not isinstance(arrtyp.elements[0], lc.PointerType) or \
not isinstance(arrtyp.elements[1], lc.ArrayType) or \
not isinstance(arrtyp.elements[2], lc.ArrayType):
return False
s1, s2 = arrtyp.elements[1:]
if s1.element != intp_type or s2.element != intp_type:
return False
if s1.count != s2.count:
return False
return True
def test():
arr = cont_array_type(5)
assert check_array(arr) == (CONTIGUOUS, 5, char_type)
arr = strided_array_type(4)
assert check_array(arr) == (STRIDED, 4, char_type)
arr = strided_soa_type(3)
assert check_array(arr) == (STRIDED_SOA, 3, char_type)
if __name__ == '__main__':
test()

View file

@ -3,6 +3,15 @@ from collections import defaultdict
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def silent_logger():
'''
Silent logger for unless we have a error message.
'''
logger.setLevel(logging.ERROR)
# comment out the line below to re-enable logging at DEBUG level.
silent_logger()
def set_debug(enabled): def set_debug(enabled):
''' '''
Side-effect: configure logger with it is not configured. Side-effect: configure logger with it is not configured.

View file

@ -2,6 +2,7 @@ from binding import *
from .namespace import llvm from .namespace import llvm
from .Value import GlobalValue, Constant, Function, Argument, Value from .Value import GlobalValue, Constant, Function, Argument, Value
from .BasicBlock import BasicBlock from .BasicBlock import BasicBlock
from .ValueSymbolTable import ValueSymbolTable
from .Attributes import Attributes from .Attributes import Attributes
from .Type import Type from .Type import Type
from .DerivedTypes import FunctionType from .DerivedTypes import FunctionType
@ -23,7 +24,7 @@ class Function:
getCallingConv = Method(CallingConv.ID) getCallingConv = Method(CallingConv.ID)
setCallingConv = Method(Void, CallingConv.ID) setCallingConv = Method(Void, CallingConv.ID)
hasGC = Method(cast(bool, Bool)) hasGC = Method(cast(Bool, bool))
getGC = Method(cast(ConstCharPtr, str)) getGC = Method(cast(ConstCharPtr, str))
setGC = Method(Void, cast(str, ConstCharPtr)) setGC = Method(Void, cast(str, ConstCharPtr))
@ -31,6 +32,7 @@ class Function:
getArgumentList = CustomMethod('Function_getArgumentList', PyObjectPtr) getArgumentList = CustomMethod('Function_getArgumentList', PyObjectPtr)
getBasicBlockList = CustomMethod('Function_getBasicBlockList', PyObjectPtr) getBasicBlockList = CustomMethod('Function_getBasicBlockList', PyObjectPtr)
getEntryBlock = Method(ref(BasicBlock)) getEntryBlock = Method(ref(BasicBlock))
getValueSymbolTable = Method(ref(ValueSymbolTable))
copyAttributesFrom = Method(Void, ptr(GlobalValue)) copyAttributesFrom = Method(Void, ptr(GlobalValue))
@ -49,6 +51,9 @@ class Function:
addFnAttr = Method(Void, Attributes.AttrVal) addFnAttr = Method(Void, Attributes.AttrVal)
removeFnAttr = Method(Void, ref(Attributes)) removeFnAttr = Method(Void, ref(Attributes))
#hasFnAttribute = Method(cast(Bool, bool), Attributes.AttrVal)
Create = Method(ptr(Function))
eraseFromParent = Method() eraseFromParent = Method()
eraseFromParent.disowning = True eraseFromParent.disowning = True

View file

@ -8,6 +8,7 @@ MDNode = llvm.Class(Value)
MDString = llvm.Class(Value) MDString = llvm.Class(Value)
User = llvm.Class(Value) User = llvm.Class(Value)
BasicBlock = llvm.Class(Value) BasicBlock = llvm.Class(Value)
ValueSymbolTable = llvm.Class()
Constant = llvm.Class(User) Constant = llvm.Class(User)
GlobalValue = llvm.Class(Constant) GlobalValue = llvm.Class(Constant)
Function = llvm.Class(GlobalValue) Function = llvm.Class(GlobalValue)

View file

@ -0,0 +1,13 @@
from binding import *
from .Value import ValueSymbolTable, Value
from .ADT.StringRef import StringRef
@ValueSymbolTable
class ValueSymbolTable:
new = Constructor()
delete = Destructor()
lookup = Method(ptr(Value), cast(str, StringRef))
empty = Method(cast(Bool, bool))
size = Method(cast(Unsigned, int))
dump = Method(Void)

View file

@ -180,6 +180,7 @@ setup(
packages = ['llvm', 'llvm.workaround', packages = ['llvm', 'llvm.workaround',
'llvm_cbuilder', 'llvm_cbuilder',
'llpython', 'llpython',
'llvm_array',
'llvmpy.api', 'llvmpy.api.llvm'], 'llvmpy.api', 'llvmpy.api.llvm'],
py_modules = ['llvmpy', py_modules = ['llvmpy',
'llvmpy._capsule', 'llvmpy._capsule',