AI-TensorFlow-Libtensorflow
view release on metacpan or search on metacpan
maint/process-capi.pl view on Meta::CPAN
option 'root_path' => (
is => 'ro',
format => 's',
doc => 'Root for TensorFlow',
default => "$FindBin::Bin/../../tensorflow/tensorflow",
isa => Path,
coerce => 1,
);
option 'lib_path' => (
is => 'ro',
format => 's',
doc => 'Root for lib',
default => "$FindBin::Bin/../lib",
isa => Path,
coerce => 1,
);
lazy capi_path => method() {
$self->root_path->child(qw(tensorflow c));
};
lazy header_paths => method() {
[ map path($_), File::Find::Rule->file
->name('*.h')
->in( $self->capi_path ) ];
};
lazy header_order => method() {
my @order = (
qr{/c/c_api.h$},
qr{/c/tf_[^.]+\.h$},
qr{/c/(ops|env|logging)\.h},
qr{kernels},
qr{/eager/},
qr{/experimental/},
qr{.*},
);
\@order;
};
lazy fdecl_re => method() {
my $re = qr{
(?>
(?<comment>
(?: // [^\n]*+ \n )*+
)
)
(?<fdecl>
^ TF_CAPI_EXPORT [^;]+ ;
)
}xm;
};
lazy sorted_header_paths => method() {
my @order = $self->header_order->@*;
my @sorted = iikeysort {
my $item = $_;
my $first = firstidx { $item =~ $_ } @order;
($first, length $_);
} $self->header_paths->@*;
\@sorted;
};
method _process_re($re) {
my @data;
my @sorted = $self->sorted_header_paths->@*;
for my $file (@sorted) {
my $txt = $file->slurp_utf8;
while( $txt =~ /$re/g ) {
push @data, {
%+,
file => $file->relative($self->root_path),
pos => pos($txt),
};
}
}
\@data;
}
lazy fdecl_data => method() {
my $re = $self->fdecl_re;
my $data = $self->_process_re($re);
# Used for defensive assertion:
# These are mostly constructors that return a value
# (i.e., not void) but also take a function pointer as a
# parameter.
my %TF_func_ptr = map { ($_ => 1) } qw(
TF_NewTensor
TF_StartThread
TF_NewKernelBuilder
TFE_NewTensorHandleFromDeviceMemory
);
for my $data (@$data) {
my ($func_name) = $data->{fdecl} =~ m/ \A [^(]*? (\w+) \s* \( (?!\s*\*) /xs;
die "Could not extract function name" unless $func_name;
# defensive assertion for parsing
my $paren_count = () = $data->{fdecl} =~ /[\(]/sg;
warn "Got $func_name, but more than one open parenthesis [(] in\n@{[ $data->{fdecl} =~ s/^/ /gr ]}\n"
if(
$paren_count != 1
&& !(
$data->{fdecl} =~ /^ TF_CAPI_EXPORT \s+ extern \s+ void \s+ \Q@{[ $func_name ]}\E \s* \(/xs
||
exists $TF_func_ptr{$func_name}
)
);
$data->{func_name} = $func_name;
}
$data;
};
method generate_capi_funcs() {
my $pod = '';
my @data = $self->fdecl_data->@*;
( run in 1.547 second using v1.01-cache-2.11-cpan-140bd7fdf52 )