Commit e9cbe1ae authored by Brice Videau's avatar Brice Videau
Browse files

Started implementing ruby bindings.

parent d4655a3d
......@@ -17,9 +17,11 @@ ZE_EXTRACT = extract_base.rb modified_include
ZE_EXTRACTED = ze_api.yaml zet_api.yaml
ZE_MODEL = ze_model.rb yaml_ast.rb ze_meta_parameters.yaml zet_meta_parameters.yaml $(ZE_EXTRACTED)
ZE_BINDINGS = ze_bindings.rb ze_refinements.rb
.SECONDARY: $(ZE_TP)
all: tracer_ze.so ze_library.rb babeltrace_ze_lib.rb
all: tracer_ze.so ze_library.rb babeltrace_ze_lib.rb $(ZE_BINDINGS)
LTTNG_FLAGS=-fPIC -g -Wall -Wextra -Wno-unused-parameter -Wno-type-limits -Werror -O3 -I./ -I./include/core -I./include/tools -I../utils/
......@@ -57,6 +59,12 @@ ze_library.rb: gen_ze_library.rb gen_ze_library_base.rb gen_probe_base.rb $(ZE_M
babeltrace_ze_lib.rb: gen_babeltrace_ze_lib.rb gen_ze_library_base.rb gen_probe_base.rb $(ZE_MODEL)
ruby $< > $@
ze_refinements.rb: gen_ze_refinements.rb gen_ze_library_base.rb gen_probe_base.rb $(ZE_MODEL)
ruby $< > $@
ze_bindings.rb: gen_ze_bindings.rb gen_ze_library_base.rb gen_probe_base.rb $(ZE_MODEL)
ruby $< > $@
# objcopy --prefix-symbols= on ze_api.a content should allow a wrapper creation
clean:
......@@ -64,6 +72,7 @@ clean:
ze_api.yaml zet_api.yaml\
$(ZE_TP) $(ZE_OBJS) $(ZE_INCL) $(ZE_SRC)\
$(ZE_STATIC_TP) $(ZE_STATIC_OBJS) $(ZE_STATIC_INCL) $(ZE_STATIC_SRC)\
$(ZE_BINDINGS)\
tracer_ze.c tracer_ze.so ze_library.rb babeltrace_ze_lib.rb
rm -fr modified_include
$(MAKE) -C ../utils clean
require_relative 'gen_ze_library_base.rb'
puts <<EOF
require_relative 'ze_library.rb'
require_relative 'ze_refinements.rb'
require_relative 'ze_bindings_base.rb'
module ZE
EOF
$all_funcs.each { |f|
type, params = f.type.to_ffi
puts <<EOF
attach_function #{to_ffi_name(f.name)},
[ #{params.join(",\n"+" "*18)} ],
#{type}
EOF
}
puts <<EOF
end
EOF
......@@ -201,11 +201,13 @@ module ZE
( major << 16 )|( minor & 0x0000ffff)
end
def self.ZE_MAJOR_VERSION(ver)
VERSION_CURRENT = ZE_MAKE_VERSION(0, 91)
def self.ZE_MAJOR_VERSION(ver = VERSION_CURRENT)
ver >> 16
end
def self.ZE_MINOR_VERSION(ver)
def self.ZE_MINOR_VERSION(ver = VERSION_CURRENT)
ver & 0x0000ffff
end
......@@ -241,78 +243,14 @@ module ZE
def to_s
"\#{self[:major]}.\#{self[:minor]}"
end
end
EOF
module YAMLCAst
class Struct
def to_ffi
res = []
members.each { |m|
mt = case m.type
when Array
m.type.to_ffi
when Pointer
":pointer"
else
to_ffi_name(m.type.name)
end
res.push [to_ffi_name(m.name), mt]
}
res
end
end
class Union
def to_ffi
res = []
members.each { |m|
mt = case m.type
when Array
m.type.to_ffi
when Pointer
":pointer"
else
to_ffi_name(m.type.name)
end
res.push [to_ffi_name(m.name), mt]
}
res
end
end
class Array
def to_ffi
t = case type
when Pointer
":pointer"
else
to_ffi_name(type.name)
end
[ t, length ]
def to_i
ZE.ZE_MAKE_VERSION(self[:major], self[:minor])
end
alias to_int to_i
end
class Function
def to_ffi
t = to_ffi_name(type.name)
p = params.collect { |par|
if par.type.kind_of?(Pointer)
if par.type.type.respond_to?(:name) &&
$all_struct_names.include?(par.type.type.name)
"#{to_class_name(par.type.type.name)}.ptr"
else
":pointer"
end
else
to_ffi_name(par.type.name)
end
}
[t, p]
end
end
end
EOF
def print_union(name, union)
members = union.to_ffi
......@@ -353,6 +291,23 @@ EOF
EOF
puts <<EOF
layout #{members.collect(&print_lambda).join(",\n"+" "*11)}
EOF
if members.first[0] == ":version"
puts <<EOF
def initialize(*args, version: nil)
super(*args)
if version
self[:version][:minor] = ZE.ZE_MINOR_VERSION(version.to_i)
self[:version][:major] = ZE.ZE_MAJOR_VERSION(version.to_i)
elsif args.length == 0
self[:version][:minor] = ZE.ZE_MINOR_VERSION()
self[:version][:major] = ZE.ZE_MAJOR_VERSION()
end
end
EOF
end
puts <<EOF
end
typedef #{to_class_name(name)}.by_value, #{to_ffi_name(name)}
......
......@@ -5,6 +5,7 @@ $all_types = $ze_api["typedefs"] + $zet_api["typedefs"]
$all_structs = $ze_api["structs"] + $zet_api["structs"]
$all_unions = $zet_api["unions"]
$all_enums = $ze_api["enums"] + $zet_api["enums"]
$all_funcs = $ze_api["functions"] + $zet_api["functions"]
$all_enum_names = []
$all_bitfield_names = []
......@@ -25,7 +26,7 @@ $all_types.each { |t|
def to_class_name(name)
mod = to_name_space(name)
n = name.gsub(/_t\z/, "").gsub(/\Azet?_/, "").split("_").collect(&:capitalize).join
mod << n.gsub("Uuid","UUID").gsub("Dditable", "DDITable").gsub(/\AFp/, "FP").gsub("Ipc", "IPC").gsub("Api","API").gsub("P2p", "P2P")
mod << n.gsub("Uuid","UUID").gsub("Dditable", "DDITable").gsub(/\AFp/, "FP").gsub("Ipc", "IPC").gsub("P2p", "P2P")
end
def to_ffi_name(name)
......@@ -50,3 +51,72 @@ $all_types.each { |t|
$all_union_names.push t.name
end
}
module YAMLCAst
class Struct
def to_ffi
res = []
members.each { |m|
mt = case m.type
when Array
m.type.to_ffi
when Pointer
":pointer"
else
to_ffi_name(m.type.name)
end
res.push [to_ffi_name(m.name), mt]
}
res
end
end
class Union
def to_ffi
res = []
members.each { |m|
mt = case m.type
when Array
m.type.to_ffi
when Pointer
":pointer"
else
to_ffi_name(m.type.name)
end
res.push [to_ffi_name(m.name), mt]
}
res
end
end
class Array
def to_ffi
t = case type
when Pointer
":pointer"
else
to_ffi_name(type.name)
end
[ t, length ]
end
end
class Function
def to_ffi
t = to_ffi_name(type.name)
p = params.collect { |par|
if par.type.kind_of?(Pointer)
if par.type.type.respond_to?(:name) &&
$all_struct_names.include?(par.type.type.name)
"#{to_class_name(par.type.type.name)}.ptr"
else
":pointer"
end
else
to_ffi_name(par.type.name)
end
}
[t, p]
end
end
end
require_relative 'gen_ze_library_base.rb'
METHOD_PREFIX = [:put, :get, :write, :read, :put_array_of, :get_array_of, :read_array_of]
def print_acessor(orig, add)
METHOD_PREFIX.each { |meth|
puts <<EOF
alias_method :#{meth}_#{add}, :#{meth}_#{orig}
EOF
}
end
puts <<EOF
module ZE
module ZERefinements
refine FFI::Pointer do
EOF
ze_bool = $all_types.find { |t| t.name == "ze_bool_t" }
print_acessor(ze_bool.type.name.gsub(/_t\z/,""), ze_bool.name)
CL_OBJECTS.each { |o|
print_acessor(:pointer, o)
}
$all_types.each { |t|
if $objects.include?(t.name)
print_acessor(:pointer, t.name)
end
}
puts <<EOF
end
end
end
EOF
using ZE::ZERefinements
module ZE
class Pointer < FFI::Pointer
def initialize(*args)
if args.length == 2 then
super(ZE::find_type(args[0]), args[1])
else
super(*args)
end
end
end
class Function < FFI::Function
def initialize(ret, args, *opts, &block)
super(ZE::find_type(ret), args.collect { |a| ZE::find_type(a) }, *opts, &block)
end
end
class MemoryPointer < FFI::MemoryPointer
def initialize(size, count = 1, clear = true)
if size.is_a?(Symbol)
size = ZE::find_type(size)
end
super(size, count, clear)
end
end
ENV["ZE_ENABLE_VALIDATION_LAYER"] = "1"
ENV["ZE_ENABLE_LOADER_INTERCEPT"] = "1"
ENV["ZE_ENABLE_PARAMETER_VALIDATION"] = "1"
if ENV["LIBZE_LOADER_SO"]
ffi_lib ENV["LIBZE_LOADER_SO"]
else
begin
ffi_lib "ze_loader"
rescue FFI::LoadError
ffi_lib "libze_loader.so.0.91"
end
end
class Error < StandardError
end
def self.error_check(result)
if result != :ZE_RESULT_SUCCESS &&
result != :ZE_ZE_RESULT_NOT_READY
raise Error, result
end
end
class Object
attr_reader :handle
def initialize(handle)
@handle = handle
end
def to_ptr
@handle
end
def self.process_property_name(pname)
res = pname.to_s.split("_").collect(&:capitalize).join
res.gsub("Uuid","UUID").gsub("Dditable", "DDITable").gsub(/\AFp/, "FP").gsub("Ipc", "IPC").gsub("P2p", "P2P")
end
def self.add_property(pname, sname: nil, fname: nil)
n = name.split("::").last
ppn = process_property_name(pname) unless sname && fname
sname = "ZE" << n << ppn unless sname
fname = "ze#{n}Get" << ppn unless fname
src = <<EOF
def #{pname}
return @#{pname} if @#{pname}
#{pname} = #{sname}::new
result = ZE.#{fname}(@handle, #{pname})
ZE.error_check(result)
@#{pname} = #{pname}
end
EOF
eval src
end
def self.add_object_array(aname, oname, fname)
src = <<EOF
def #{aname}
return @#{aname} if @#{aname}
pCount = MemoryPointer::new(:uint32_t)
result = ZE.#{fname}(@handle, pCount, nil)
ZE.error_check(result)
count = pCount.read(:uint32)
return [] if count == 0
pArr = MemoryPointer::new(:pointer, count)
result = ZE.#{fname}(@handle, pCount, pArr)
ZE.error_check(result)
@#{aname} = pArr.read_array_of_pointer(count).collect { |h| #{oname}::new(h) }
end
EOF
eval src
end
def self.add_array_property(aname, sname, fname)
src = <<EOF
def #{aname}
return @#{aname} if @#{aname}
pCount = MemoryPointer::new(:uint32_t)
result = ZE.#{fname}(@handle, pCount, nil)
ZE.error_check(result)
count = pCount.read(:uint32)
return [] if count == 0
pArr = MemoryPointer::new(#{sname}, count)
sz = #{sname}.size
#{aname} = count.times.collect { |i| #{sname}::new(pArr.slice(sz * i, sz)) }
result = ZE.#{fname}(@handle, pCount, #{aname}.first)
ZE.error_check(result)
@#{aname} = #{aname}
end
EOF
eval src
end
end
class Driver < Object
add_property :api_version, sname: :ZEApiVersion
add_property :properties
add_property :ipc_properties
add_object_array :devices, :Device, :zeDeviceGet
end
class Device < Object
add_property :properties
add_object_array :sub_devices, :Device, :zeDeviceGetSubDevices
add_property :compute_properties
add_property :kernel_properties
add_array_property :memory_properties, :ZEDeviceMemoryProperties, :zeDeviceGetMemoryProperties
add_property :memory_access_properties
add_property :cache_properties
add_property :image_properties
def p2p_properties(device)
p2p_properties = ZEDeviceP2PProperties::new
result = ZE.zeDeviceGetP2PProperties(@handle, device, p2p_properties)
ZE.error_check(result)
return p2p_properties
end
def can_access_peer?(device)
can_access_peer = MemoryPointer::new(:ze_bool_t)
result = ZE.zeDeviceCanAccessPeer(@handle, device, can_access_peer)
ZE.error_check(result)
return can_access_peer.read_ze_bool_t == 1
end
def set_last_level_cache_config(cache_config = :ZE_CACHE_CONFIG_DEFAULT)
result = ZE.zeDeviceSetLastLevelCacheConfig(@handle, cache_config)
ZE.error_check(result)
cache_config
end
alias last_level_cache_config= set_last_level_cache_config
end
def self.ze_init(flags: 0)
result = zeInit(flags)
error_check(result)
nil
end
def self.zet_init(flags: 0)
result = zetInit(flags)
error_check(result)
nil
end
def self.init(flags: 0)
ze_init(flags: flags)
zet_init(flags: flags)
nil
end
def self.drivers
return @drivers if @drivers
pCount = MemoryPointer::new(:uint32_t)
result = zeDriverGet(pCount, nil);
error_check(result)
count = pCount.read(:uint32)
return [] if count == 0
phDrivers = MemoryPointer::new(:ze_driver_handle_t, count)
result = zeDriverGet(pCount, phDrivers);
error_check(result)
@drivers = phDrivers.read_array_of_ze_driver_handle_t(count).collect { |h| Driver::new(h) }
end
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment