view release on metacpan or search on metacpan
CONTRIBUTING view on Meta::CPAN
"Contribution" shall mean any original work of authorship, including any changes or additions or enhancements to an existing work, that is intentionally submitted by You to this repository for inclusion in, or documentation of, any of the products or...
2. Assignment of Copyright. Subject to the terms and conditions of this Agreement, and for good and valuable consideration, receipt of which You acknowledge, You hereby transfer to the Delaware corporation named Auto-Parallel Technologies, Inc. with...
You hereby agree that if You have or acquire hereafter any patent or interface copyright or other intellectual property interest dominating the software or documentation contributed to by the Work (or use of that software or documentation), such domi...
You hereby represent and warrant that You are the sole copyright holder for the Work and that You have the right and power to enter into this legally-binding contractual agreement. You hereby indemnify and hold harmless APTech, its heirs, assignees,...
3. Grant of Patent License. Subject to the terms and conditions of this Agreement, You hereby grant to APTech and to recipients of software distributed by APTech a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as ...
4. You represent that you are legally entitled to assign the above copyright and grant the above patent license. If your employer(s) or contractee(s) have rights to intellectual property that you create that includes your Contributions, then you rep...
5. You represent that each of Your Contributions is Your original creation and is not subject to any third-party license or other restriction (including, but not limited to, related patents and trademarks) of which you are personally aware and which ...
6. You agree to submit written notification to Team APTech's Leadership of any facts or circumstances of which you become aware that would make the representations of this Agreement inaccurate in any respect.
[ END, APTECH FAMILY COPYRIGHT ASSIGNMENT AGREEMENT ]
<<<=== LEGAL OVERVIEW ===>>>
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2022 Auto-Parallel Technologies, Inc
lib/AI/TensorFlow/Libtensorflow.pm view on Meta::CPAN
my $ffi = AI::TensorFlow::Libtensorflow::Lib->ffi;
FFI::C->ffi($ffi);
$ffi->mangler(AI::TensorFlow::Libtensorflow::Lib->mangler_default);
sub new {
my ($class) = @_;
bless {}, $class;
}
$ffi->attach( 'Version' => [], 'string' );#}}}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
lib/AI/TensorFlow/Libtensorflow/ApiDefMap.pm view on Meta::CPAN
# ABSTRACT: Maps Operation to API description
$AI::TensorFlow::Libtensorflow::ApiDefMap::VERSION = '0.0.7';
use strict;
use warnings;
use namespace::autoclean;
use AI::TensorFlow::Libtensorflow::Lib qw(arg);
my $ffi = AI::TensorFlow::Libtensorflow::Lib->ffi;
$ffi->mangler(AI::TensorFlow::Libtensorflow::Lib->mangler_default);
$ffi->attach( [ 'NewApiDefMap' => 'New' ] => [
arg 'TF_Buffer' => 'op_list_buffer',
arg 'TF_Status' => 'status',
] => 'TF_ApiDefMap' => sub {
my ($xs, $class, @rest) = @_;
$xs->(@rest);
});
$ffi->attach( ['DeleteApiDefMap' => 'DESTROY'] => [
arg 'TF_ApiDefMap' => 'apimap'
] => 'void');
$ffi->attach( [ 'ApiDefMapPut' => 'Put' ] => [
arg 'TF_ApiDefMap' => 'api_def_map',
arg 'tf_text_buffer' => [qw(text text_len)],
arg 'TF_Status' => 'status',
] => 'void' );
$ffi->attach( ['ApiDefMapGet' => 'Get' ] => [
arg 'TF_ApiDefMap' => 'api_def_map',
arg 'tf_text_buffer' => [qw(name name_len)],
arg 'TF_Status' => 'status',
] => 'TF_Buffer');
1;
__END__
=pod
lib/AI/TensorFlow/Libtensorflow/Buffer.pm view on Meta::CPAN
my $closure = $ffi->closure( $coderef );
$closure->sticky;
$self->{_data_deallocator_closure} = $closure;
my $opaque = $ffi->cast('data_deallocator_t', 'opaque', $closure);
$self->_data_deallocator( $opaque );
}
$ffi->attach( [ 'NewBuffer' => 'New' ] => [] => 'TF_Buffer' );
$ffi->attach( [ 'NewBufferFromString' => 'NewFromString' ] => [
arg 'tf_buffer_buffer' => [qw(proto proto_len)]
] => 'TF_Buffer' => sub {
my ($xs, $class, @rest) = @_;
$xs->(@rest);
});
$ffi->attach( [ 'DeleteBuffer' => 'DESTROY' ] => [ 'TF_Buffer' ], 'void' );
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
lib/AI/TensorFlow/Libtensorflow/DataType.pm view on Meta::CPAN
'@DTYPES' => [ sort { $$a <=> $$b } values %_DTYPES ],
]
);
use namespace::autoclean;
my $ffi = AI::TensorFlow::Libtensorflow::Lib->ffi;
$ffi->mangler(AI::TensorFlow::Libtensorflow::Lib->mangler_for_object('DataType'));
$ffi->type('object(AI::TensorFlow::Libtensorflow::DataType,int)', 'TF_DataType');
$ffi->attach( 'Size' => ['TF_DataType'] => 'size_t' );
use overload
'==' => '_op_num_equals',
'eq' => '_op_eq',
'""' => '_op_stringify';
sub _op_num_equals {
my ($a, $b, $swap) = @_;
my $int_a = ref $a ? 0+$$a : 0+$a;
lib/AI/TensorFlow/Libtensorflow/DeviceList.pm view on Meta::CPAN
# ABSTRACT: A list of devices available for the session to run on
$AI::TensorFlow::Libtensorflow::DeviceList::VERSION = '0.0.7';
use strict;
use warnings;
use namespace::autoclean;
use AI::TensorFlow::Libtensorflow::Lib qw(arg);
my $ffi = AI::TensorFlow::Libtensorflow::Lib->ffi;
$ffi->mangler(AI::TensorFlow::Libtensorflow::Lib->mangler_default);
$ffi->attach( [ 'DeleteDeviceList' => 'DESTROY' ] => [
arg TF_DeviceList => 'list',
] => 'void' );
$ffi->attach( [ 'DeviceListCount' => 'Count' ] => [
arg TF_DeviceList => 'list',
] => 'int' );
my %methods = (
Name => 'string',
Type => 'string',
MemoryBytes => 'int64_t',
Incarnation => 'uint64_t',
);
for my $method (keys %methods) {
$ffi->attach( [ "DeviceList${method}" => $method ] => [
arg TF_DeviceList => 'list',
arg int => 'index',
arg TF_Status => 'status'
] => $methods{$method} );
}
### From tensorflow/core/framework/types.cc
my %DEVICE_TYPES = (
DEFAULT => "DEFAULT",
CPU => "CPU",
lib/AI/TensorFlow/Libtensorflow/Eager/Context.pm view on Meta::CPAN
package AI::TensorFlow::Libtensorflow::Eager::Context;
# ABSTRACT: Eager context
$AI::TensorFlow::Libtensorflow::Eager::Context::VERSION = '0.0.7';
use strict;
use warnings;
use AI::TensorFlow::Libtensorflow::Lib qw(arg);
my $ffi = AI::TensorFlow::Libtensorflow::Lib->ffi;
$ffi->mangler(AI::TensorFlow::Libtensorflow::Lib->mangler_default);
$ffi->attach( [ 'NewContext' => 'New' ] => [
arg TFE_ContextOptions => 'opts',
arg TF_Status => 'status'
] => 'TFE_Context' => sub {
my ($xs, $class, @rest) = @_;
$xs->(@rest);
} );
__END__
=pod
lib/AI/TensorFlow/Libtensorflow/Eager/ContextOptions.pm view on Meta::CPAN
package AI::TensorFlow::Libtensorflow::Eager::ContextOptions;
# ABSTRACT: Eager context options
$AI::TensorFlow::Libtensorflow::Eager::ContextOptions::VERSION = '0.0.7';
use strict;
use warnings;
use AI::TensorFlow::Libtensorflow::Lib qw(arg);
my $ffi = AI::TensorFlow::Libtensorflow::Lib->ffi;
$ffi->mangler(AI::TensorFlow::Libtensorflow::Lib->mangler_default);
$ffi->attach( [ 'NewContextOptions' => 'New' ] => [
] => 'TFE_ContextOptions' );
$ffi->attach( [ 'DeleteContextOptions' => 'DESTROY' ] => [
arg TFE_ContextOptions => 'options'
] => 'void' );
1;
__END__
=pod
lib/AI/TensorFlow/Libtensorflow/Graph.pm view on Meta::CPAN
$AI::TensorFlow::Libtensorflow::Graph::VERSION = '0.0.7';
use strict;
use warnings;
use namespace::autoclean;
use AI::TensorFlow::Libtensorflow::Lib qw(arg);
use AI::TensorFlow::Libtensorflow::Buffer;
use AI::TensorFlow::Libtensorflow::Output;
my $ffi = AI::TensorFlow::Libtensorflow::Lib->ffi;
$ffi->mangler(AI::TensorFlow::Libtensorflow::Lib->mangler_default);
$ffi->attach( [ 'NewGraph' => 'New' ] => [] => 'TF_Graph' );
$ffi->attach( [ 'DeleteGraph' => 'DESTROY' ] => [ arg 'TF_Graph' => 'self' ], 'void' );
$ffi->attach( [ 'GraphImportGraphDef' => 'ImportGraphDef' ] => [
arg 'TF_Graph' => 'graph',
arg 'TF_Buffer' => 'graph_def',
arg 'TF_ImportGraphDefOptions' => 'options',
arg 'TF_Status' => 'status',
] => 'void' );
$ffi->attach( [ 'GraphImportGraphDefWithResults' => 'ImportGraphDefWithResults' ] => [
arg TF_Graph => 'graph',
arg TF_Buffer => 'graph_def',
arg TF_ImportGraphDefOptions => 'options',
arg TF_Status => 'status',
] => 'TF_ImportGraphDefResults');
$ffi->attach( [ 'GraphImportGraphDefWithReturnOutputs' => 'ImportGraphDefWithReturnOutputs' ] => [
arg TF_Graph => 'graph',
arg TF_Buffer => 'graph_def',
arg TF_ImportGraphDefOptions => 'options',
arg TF_Output_struct_array => 'return_outputs',
arg int => 'num_return_outputs',
arg TF_Status => 'status',
] => 'void' => sub {
my ($xs, $graph, $graph_def, $options, $status) = @_;
my $num_return_outputs = $options->NumReturnOutputs;
return [] if $num_return_outputs == 0;
my $return_outputs = AI::TensorFlow::Libtensorflow::Output->_adef->create( $num_return_outputs );
$xs->($graph, $graph_def, $options,
$return_outputs, $num_return_outputs,
$status);
return AI::TensorFlow::Libtensorflow::Output->_from_array( $return_outputs );
});
$ffi->attach( [ 'GraphOperationByName' => 'OperationByName' ] => [
arg 'TF_Graph' => 'graph',
arg 'string' => 'oper_name',
] => 'TF_Operation' );
$ffi->attach( [ 'GraphSetTensorShape' => 'SetTensorShape' ] => [
arg 'TF_Graph' => 'graph',
arg 'TF_Output' => 'output',
arg 'tf_dims_buffer' => [qw(dims num_dims)],
arg 'TF_Status' => 'status',
] => 'void');
$ffi->attach( ['GraphGetTensorShape' => 'GetTensorShape'] => [
arg 'TF_Graph' => 'graph',
arg 'TF_Output' => 'output',
arg 'tf_dims_buffer' => [qw(dims num_dims)],
arg 'TF_Status' => 'status',
] => 'void' => sub {
my ($xs, @rest) = @_;
my ($graph, $output, $status) = @rest;
my $dims = [ (0)x($graph->GetTensorNumDims($output, $status)) ];
$xs->($graph, $output, $dims, $status);
return $dims;
});
$ffi->attach( [ 'GraphGetTensorNumDims' => 'GetTensorNumDims' ] => [
arg 'TF_Graph' => 'graph',
arg 'TF_Output' => 'output',
arg 'TF_Status' => 'status',
] => 'int');
$ffi->attach( [ 'GraphNextOperation' => 'NextOperation' ] => [
arg 'TF_Graph' => 'graph',
arg 'size_t*' => 'pos',
] => 'TF_Operation');
$ffi->attach( [ 'UpdateEdge' => 'UpdateEdge' ] => [
arg 'TF_Graph' => 'graph',
arg 'TF_Output' => 'new_src',
arg 'TF_Input' => 'dst',
arg 'TF_Status' => 'status',
] => 'void');
$ffi->attach([ 'GraphToGraphDef' => 'ToGraphDef' ] => [
arg 'TF_Graph' => 'graph',
arg 'TF_Buffer' => 'output_graph_def',
arg 'TF_Status' => 'status',
] => 'void');
$ffi->attach( [ 'GraphGetOpDef' => 'GetOpDef' ] => [
arg TF_Graph => 'graph',
arg string => 'op_name',
arg TF_Buffer => 'output_op_def',
arg TF_Status => 'status',
] => 'void');
1;
__END__
lib/AI/TensorFlow/Libtensorflow/ImportGraphDefOptions.pm view on Meta::CPAN
# ABSTRACT: Holds options that can be passed to ::Graph::ImportGraphDef
$AI::TensorFlow::Libtensorflow::ImportGraphDefOptions::VERSION = '0.0.7';
use strict;
use warnings;
use namespace::autoclean;
use AI::TensorFlow::Libtensorflow::Lib qw(arg);
my $ffi = AI::TensorFlow::Libtensorflow::Lib->ffi;
$ffi->mangler(AI::TensorFlow::Libtensorflow::Lib->mangler_default);
$ffi->attach( [ 'NewImportGraphDefOptions' => 'New' ] => [] => 'TF_ImportGraphDefOptions' );
$ffi->attach( [ 'DeleteImportGraphDefOptions' => 'DESTROY' ] => [
arg 'TF_ImportGraphDefOptions' => 'self',
] => 'void' );
$ffi->attach( [ 'ImportGraphDefOptionsSetPrefix' => 'SetPrefix' ] => [
arg 'TF_ImportGraphDefOptions' => 'opts',
arg 'string' => 'prefix',
] => 'void' );
$ffi->attach( [ 'ImportGraphDefOptionsAddInputMapping' => 'AddInputMapping' ] => [
arg 'TF_ImportGraphDefOptions' => 'opts',
arg 'string' => 'src_name',
arg 'int' => 'src_index',
arg 'TF_Output' => 'dst',
] => 'void');
$ffi->attach( [ 'ImportGraphDefOptionsAddReturnOutput' => 'AddReturnOutput' ] => [
arg TF_ImportGraphDefOptions => 'opts',
arg string => 'oper_name',
arg int => 'index',
] => 'void' );
$ffi->attach( [ 'ImportGraphDefOptionsNumReturnOutputs' => 'NumReturnOutputs' ] => [
arg TF_ImportGraphDefOptions => 'opts',
] => 'int');
$ffi->attach( [ 'ImportGraphDefOptionsAddReturnOperation' => 'AddReturnOperation' ] => [
arg TF_ImportGraphDefOptions => 'opts',
arg string => 'oper_name',
] => 'void' );
$ffi->attach( [ 'ImportGraphDefOptionsNumReturnOperations' => 'NumReturnOperations' ] => [
arg TF_ImportGraphDefOptions => 'opts',
] => 'int' );
$ffi->attach( [ 'ImportGraphDefOptionsAddControlDependency' => 'AddControlDependency' ] => [
arg TF_ImportGraphDefOptions => 'opts',
arg TF_Operation => 'oper',
] => 'void' );
$ffi->attach( [ 'ImportGraphDefOptionsRemapControlDependency' => 'RemapControlDependency' ] => [
arg TF_ImportGraphDefOptions => 'opts',
arg string => 'src_name',
arg TF_Operation => 'dst',
] => 'void' );
1;
__END__
=pod
lib/AI/TensorFlow/Libtensorflow/ImportGraphDefResults.pm view on Meta::CPAN
use strict;
use warnings;
use namespace::autoclean;
use AI::TensorFlow::Libtensorflow::Lib qw(arg);
use FFI::Platypus::Buffer qw(buffer_to_scalar window);
use List::Util ();
my $ffi = AI::TensorFlow::Libtensorflow::Lib->ffi;
$ffi->mangler(AI::TensorFlow::Libtensorflow::Lib->mangler_default);
$ffi->attach( [ 'DeleteImportGraphDefResults' => 'DESTROY' ] => [
arg TF_ImportGraphDefResults => 'results',
] => 'void' );
$ffi->attach( [ 'ImportGraphDefResultsReturnOutputs' => 'ReturnOutputs' ] => [
arg TF_ImportGraphDefResults => 'results',
arg 'int*' => 'num_outputs',
arg 'opaque*' => { id => 'outputs', type => 'TF_Output_struct_array*' },
] => 'void' => sub {
my ($xs, $results) = @_;
my $num_outputs;
my $outputs_array = undef;
$xs->($results, \$num_outputs, \$outputs_array);
return [] if $num_outputs == 0;
my $sizeof_output = $ffi->sizeof('TF_Output');
window(my $outputs_packed, $outputs_array, $sizeof_output * $num_outputs );
# due to unpack, these are copies (no longer owned by $results)
my @outputs = map bless(\$_, "AI::TensorFlow::Libtensorflow::Output"),
unpack "(a${sizeof_output})*", $outputs_packed;
return \@outputs;
});
$ffi->attach( [ 'ImportGraphDefResultsReturnOperations' => 'ReturnOperations' ] => [
arg TF_ImportGraphDefResults => 'results',
arg 'int*' => 'num_opers',
arg 'opaque*' => { id => 'opers', type => 'TF_Operation_array*' },
] => 'void' => sub {
my ($xs, $results) = @_;
my $num_opers;
my $opers_array = undef;
$xs->($results, \$num_opers, \$opers_array);
return [] if $num_opers == 0;
my $opers_array_base_packed = buffer_to_scalar($opers_array,
$ffi->sizeof('opaque') * $num_opers );
my @opers = map {
$ffi->cast('opaque', 'TF_Operation', $_ )
} unpack "(@{[ AI::TensorFlow::Libtensorflow::Lib::_pointer_incantation ]})*", $opers_array_base_packed;
return \@opers;
} );
$ffi->attach( [ 'ImportGraphDefResultsMissingUnusedInputMappings' => 'MissingUnusedInputMappings' ] => [
arg TF_ImportGraphDefResults => 'results',
arg 'int*' => 'num_missing_unused_input_mappings',
arg 'opaque*' => { id => 'src_names', ctype => 'const char***' },
arg 'opaque*' => { id => 'src_indexes', ctype => 'int**' },
] => 'void' => sub {
my ($xs, $results) = @_;
my $num_missing_unused_input_mappings;
my $src_names;
my $src_indexes;
$xs->($results,
lib/AI/TensorFlow/Libtensorflow/Lib/_Alloc.pm view on Meta::CPAN
# If _aligned_alloc() implementation needs the size to be a multiple of the
# alignment.
our $_ALIGNED_ALLOC_ALIGNMENT_MULTIPLE = 0;
my $ffi = FFI::Platypus->new;
$ffi->lib(undef);
if( $ffi->find_symbol('aligned_alloc') ) {
# C11 aligned_alloc()
# NOTE: C11 aligned_alloc not available on Windows.
# void *aligned_alloc(size_t alignment, size_t size);
$ffi->attach( [ 'aligned_alloc' => '_aligned_alloc' ] =>
[ 'size_t', 'size_t' ] => 'opaque' );
*_aligned_free = *free;
$_ALIGNED_ALLOC_ALIGNMENT_MULTIPLE = 1;
} else {
# Pure Perl _aligned_alloc()
quote_sub '_aligned_alloc', q{
my ($alignment, $size) = @_;
# $alignment must fit in 8-bits
die "\$alignment must be <= 255" if $alignment > 0xFF;
lib/AI/TensorFlow/Libtensorflow/Manual/CAPI.pod view on Meta::CPAN
/* From <tensorflow/c/eager/c_api.h> */
TF_CAPI_EXPORT extern void TFE_OpAddInputList(TFE_Op* op,
TFE_TensorHandle** inputs,
int num_inputs,
TF_Status* status);
=head2 TFE_OpGetFlatInputCount
=over 2
Fetches the current number of inputs attached to `op`.
Does not use the operation's definition to determine how many inputs should
be attached. It is intended for use with TFE_OpGetFlatInput to inspect an
already-finalized operation.
Note that TFE_OpGetFlatInputCount and TFE_OpGetFlatInput operate on a flat
sequence of inputs, unlike TFE_OpGetInputLength (for getting the length of a
particular named input list, which may only be part of the op's inputs).
=back
/* From <tensorflow/c/eager/c_api.h> */
TF_CAPI_EXPORT extern int TFE_OpGetFlatInputCount(const TFE_Op* op,
lib/AI/TensorFlow/Libtensorflow/Operation.pm view on Meta::CPAN
}
sub _from_array {
my ($class, $array) = @_;
[
map {
$ffi->cast('opaque', 'TF_Operation', $array->[$_]->p);
} 0..$array->count-1
]
}
$ffi->attach( [ 'OperationName' => 'Name' ], [
arg 'TF_Operation' => 'oper',
] => 'string');
$ffi->attach( [ 'OperationOpType' => 'OpType' ], [
arg 'TF_Operation' => 'oper',
] => 'string');
$ffi->attach( [ 'OperationDevice' => 'Device' ], [
arg 'TF_Operation' => 'oper',
] => 'string');
$ffi->attach( [ 'OperationNumOutputs' => 'NumOutputs' ], [
arg 'TF_Operation' => 'oper',
] => 'int');
$ffi->attach( [ 'OperationOutputType' => 'OutputType' ] => [
arg 'TF_Output' => 'oper_out',
] => 'TF_DataType' => sub {
my ($xs, $self, $output) = @_;
# TODO coerce from LibtfPartialOutput here
$xs->($output);
} );
$ffi->attach( [ 'OperationNumInputs' => 'NumInputs' ] => [
arg 'TF_Operation' => 'oper',
] => 'int' );
$ffi->attach( [ 'OperationInputType' => 'InputType' ] => [
arg 'TF_Input' => 'oper_in',
] => 'TF_DataType' => sub {
my ($xs, $self, $input) = @_;
# TODO coerce from LibtfPartialInput here
$xs->($input);
});
$ffi->attach( [ 'OperationNumControlInputs' => 'NumControlInputs' ] => [
arg 'TF_Operation' => 'oper',
] => 'int' );
$ffi->attach( [ 'OperationNumControlOutputs' => 'NumControlOutputs' ] => [
arg 'TF_Operation' => 'oper',
] => 'int' );
$ffi->attach( [ OperationOutputListLength => 'OutputListLength' ] => [
arg 'TF_Operation' => 'oper',
arg 'string' => 'arg_name',
arg 'TF_Status' => 'status',
] => 'int');
$ffi->attach( [ 'OperationInputListLength' => 'InputListLength' ] => [
arg 'TF_Operation' => 'oper',
arg 'string' => 'arg_name',
arg 'TF_Status' => 'status',
] => 'int' );
$ffi->attach( [ 'OperationInput' => 'Input' ] => [
arg 'TF_Input' => 'oper_in',
] => 'TF_Output' => sub {
my ($xs, $self, $input) = @_;
# TODO coerce from LibtfPartialInput here
$xs->($input);
});
$ffi->attach( [ 'OperationAllInputs' => 'AllInputs' ] => [
arg 'TF_Operation' => 'oper',
# TODO make OutputArray
arg 'TF_Output_struct_array' => 'inputs',
arg 'int' => 'max_inputs',
] => 'void' => sub {
my ($xs, $oper) = @_;
my $max_inputs = $oper->NumInputs;
return [] if $max_inputs == 0;
my $inputs = AI::TensorFlow::Libtensorflow::Output->_adef->create(0 + $max_inputs);
$xs->($oper, $inputs, $max_inputs);
return AI::TensorFlow::Libtensorflow::Output->_from_array($inputs);
});
$ffi->attach( [ 'OperationGetControlInputs' => 'GetControlInputs' ] => [
arg 'TF_Operation' => 'oper',
arg 'TF_Operation_array' => 'control_inputs',
arg 'int' => 'max_control_inputs',
] => 'void' => sub {
my ($xs, $oper) = @_;
my $max_inputs = $oper->NumControlInputs;
return [] if $max_inputs == 0;
my $inputs = AI::TensorFlow::Libtensorflow::Operation->_adef->create(0 + $max_inputs);
$xs->($oper, $inputs, $max_inputs);
return AI::TensorFlow::Libtensorflow::Operation->_from_array($inputs);
});
$ffi->attach( [ 'OperationGetControlOutputs' => 'GetControlOutputs' ] => [
arg 'TF_Operation' => 'oper',
arg 'TF_Operation_array' => 'control_outputs',
arg 'int' => 'max_control_outputs',
] => 'void' => sub {
my ($xs, $oper) = @_;
my $max_outputs = $oper->NumControlOutputs;
return [] if $max_outputs == 0;
my $outputs = AI::TensorFlow::Libtensorflow::Operation->_adef->create(0 + $max_outputs);
$xs->($oper, $outputs, $max_outputs);
return AI::TensorFlow::Libtensorflow::Operation->_from_array($outputs);
});
$ffi->attach( [ 'OperationOutputNumConsumers' => 'OutputNumConsumers' ] => [
arg 'TF_Output' => 'oper_out',
], 'int' => sub {
my ($xs, $self, $output) = @_;
# TODO coerce from LibtfPartialOutput here
$xs->($output);
});
$ffi->attach( [ 'OperationOutputConsumers' => 'OutputConsumers' ] => [
# TODO simplify API
arg 'TF_Output' => 'oper_out',
arg 'TF_Input_struct_array' => 'consumers',
arg 'int' => 'max_consumers',
] => 'int' => sub {
my ($xs, $self, $output) = @_;
my $max_consumers = $self->OutputNumConsumers( $output );
my $consumers = AI::TensorFlow::Libtensorflow::Input->_adef->create( $max_consumers );
my $count = $xs->($output, $consumers, $max_consumers);
return AI::TensorFlow::Libtensorflow::Input->_from_array( $consumers );
lib/AI/TensorFlow/Libtensorflow/OperationDescription.pm view on Meta::CPAN
$ffi->load_custom_type(PackableArrayRef('Int64ArrayRef', pack_type => 'q')
=> 'tf_attr_int_list'
);
$ffi->load_custom_type(PackableArrayRef('Float32ArrayRef', pack_type => 'f')
=> 'tf_attr_float_list'
);
$ffi->load_custom_type(PackableArrayRef('BoolArrayRef', pack_type => 'C')
=> 'tf_attr_bool_list',
);
$ffi->attach( [ 'NewOperation' => 'New' ] => [
arg 'TF_Graph' => 'graph',
arg 'string' => 'op_type',
arg 'string' => 'oper_name',
] => 'TF_OperationDescription' => sub {
my ($xs, $class, @rest) = @_;
$xs->(@rest);
});
$ffi->attach( [ 'NewOperationLocked' => 'NewLocked' ] => [
arg 'TF_Graph' => 'graph',
arg 'string' => 'op_type',
arg 'string' => 'oper_name',
] => 'TF_OperationDescription' );
$ffi->attach( 'SetDevice' => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'device',
] => 'void');
$ffi->attach( 'AddInput' => [
arg 'TF_OperationDescription' => 'desc',
arg 'TF_Output' => 'input',
] => 'void');
$ffi->attach( AddInputList => [
arg 'TF_OperationDescription' => 'desc',
arg 'TF_Output_struct_array' => 'inputs',
arg 'int' => 'num_inputs',
] => 'void' => sub {
my $xs = shift;
$_[1] = AI::TensorFlow::Libtensorflow::Output->_as_array( @{ $_[1] } );
$_[2] = $_[1]->count;
$xs->(@_);
});
$ffi->attach( AddControlInput => [
arg 'TF_OperationDescription' => 'desc',
arg 'TF_Operation' => 'input',
] => 'void');
$ffi->attach( ColocateWith => [
arg 'TF_OperationDescription' => 'desc',
arg 'TF_Operation' => 'op',
] => 'void');
$ffi->attach( SetAttrString => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
arg tf_attr_string_buffer => [qw(value length)],
] => 'void');
$ffi->attach(SetAttrStringList => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
arg 'tf_attr_string_list' => [qw(values lengths num_values)],
] => 'void');
$ffi->attach( SetAttrInt => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
arg int64_t => 'value',
] => 'void');
$ffi->attach( SetAttrIntList => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
arg 'tf_attr_int_list' => [qw(values num_values)],
] => 'void');
$ffi->attach( SetAttrFloat => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
arg 'float' => 'value',
] => 'void');
$ffi->attach(SetAttrFloatList => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
arg 'tf_attr_float_list' => [qw(values num_values)],
] => 'void');
$ffi->attach( SetAttrBool => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
arg 'unsigned char' => 'value',
] => 'void');
$ffi->attach( SetAttrBoolList => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
arg 'tf_attr_bool_list' => [qw(values num_values)],
] => 'void');
$ffi->attach(SetAttrType => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
arg 'TF_DataType' => 'value',
] => 'void');
$ffi->attach( SetAttrTypeList => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
# TODO
arg 'opaque' => 'values',
#arg 'TF_DataType*' => 'values',
arg 'int' => 'num_values',
]);
$ffi->attach( SetAttrPlaceholder => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
arg 'string' => 'placeholder',
] => 'void');
$ffi->attach( SetAttrFuncName => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
arg 'tf_attr_string_buffer' => [qw(value length)],
] => 'void');
$ffi->attach( SetAttrShape => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
arg 'tf_dims_buffer' => [qw(dims num_dims)],
] => 'void');
$ffi->attach( SetAttrShapeList => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
# TODO
arg 'opaque' => 'const int64_t* const* dims',
arg 'opaque' => 'const int* num_dims',
arg 'int' => 'num_shapes',
]);
$ffi->attach(SetAttrTensorShapeProto => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
arg 'tf_tensor_shape_proto_buffer' => [qw(proto proto_len)],
arg 'TF_Status' => 'status',
] => 'void');
$ffi->attach( SetAttrTensorShapeProtoList => [
# TODO
] => 'void');
$ffi->attach( SetAttrTensor => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
arg 'TF_Tensor' => 'value',
arg 'TF_Status' => 'status',
] => 'void');
$ffi->attach( SetAttrTensorList => [
# TODO
] => 'void');
$ffi->attach(SetAttrValueProto => [
arg 'TF_OperationDescription' => 'desc',
arg 'string' => 'attr_name',
arg 'tf_attr_value_proto_buffer' => [qw(proto proto_len)],
arg 'TF_Status' => 'status',
] => 'void');
$ffi->attach(FinishOperation => [
arg 'TF_OperationDescription' => 'desc',
arg 'TF_Status' => 'status',
] => 'TF_Operation');
$ffi->attach(FinishOperationLocked => [
arg 'TF_OperationDescription' => 'desc',
arg 'TF_Status' => 'status',
] => 'TF_Operation');
1;
__END__
=pod
lib/AI/TensorFlow/Libtensorflow/Session.pm view on Meta::CPAN
use AI::TensorFlow::Libtensorflow;
use AI::TensorFlow::Libtensorflow::Lib qw(arg);;
use AI::TensorFlow::Libtensorflow::Tensor;
use AI::TensorFlow::Libtensorflow::Output;
use FFI::Platypus::Buffer qw(window scalar_to_pointer);
my $ffi = AI::TensorFlow::Libtensorflow::Lib->ffi;
$ffi->mangler(AI::TensorFlow::Libtensorflow::Lib->mangler_default);
$ffi->attach( [ 'NewSession' => 'New' ] =>
[
arg 'TF_Graph' => 'graph',
arg 'TF_SessionOptions' => 'opt',
arg 'TF_Status' => 'status',
],
=> 'TF_Session' => sub {
my ($xs, $class, @rest) = @_;
return $xs->(@rest);
});
$ffi->attach( [ 'LoadSessionFromSavedModel' => 'LoadFromSavedModel' ] => [
arg TF_SessionOptions => 'session_options',
arg opaque => { id => 'run_options', ffi_type => 'TF_Buffer', maybe => 1 },
arg string => 'export_dir',
arg 'string[]' => 'tags',
arg int => 'tags_len',
arg TF_Graph => 'graph',
arg opaque => { id => 'meta_graph_def', ffi_type => 'TF_Buffer', maybe => 1 },
arg TF_Status => 'status',
] => 'TF_Session' => sub {
my ($xs, $class, @rest) = @_;
lib/AI/TensorFlow/Libtensorflow/Session.pm view on Meta::CPAN
$xs->(
$session_options,
$run_options,
$export_dir,
$tags, $tags_len,
$graph, $meta_graph_def,
$status
);
} );
$ffi->attach( [ 'SessionRun' => 'Run' ] =>
[
arg 'TF_Session' => 'session',
# RunOptions
arg 'opaque' => { id => 'run_options', ffi_type => 'TF_Buffer', maybe => 1 },
# Input TFTensors
arg 'TF_Output_struct_array' => 'inputs',
arg 'TF_Tensor_array' => 'input_values',
arg 'int' => 'ninputs',
lib/AI/TensorFlow/Libtensorflow/Session.pm view on Meta::CPAN
my @target_opers_args = defined $target_opers
? do {
my $target_opers_a = AI::TensorFlow::Libtensorflow::Operation->_as_array( @$target_opers );
( $target_opers_a, $target_opers_a->count )
}
: ( undef, 0 );
return @target_opers_args;
}
$ffi->attach([ 'SessionPRunSetup' => 'PRunSetup' ] => [
arg TF_Session => 'session',
# Input names
arg TF_Output_struct_array => 'inputs',
arg int => 'ninputs',
# Output names
arg TF_Output_struct_array => 'outputs',
arg int => 'noutputs',
# Target operations
arg opaque => { id => 'target_opers', ffi_type => 'TF_Operation_array', maybe => 1 },
arg int => 'ntargets',
lib/AI/TensorFlow/Libtensorflow/Session.pm view on Meta::CPAN
return unless defined $handle;
window( my $handle_window, $handle );
my $handle_obj = bless \\$handle_window,
'AI::TensorFlow::Libtensorflow::Session::_PRHandle';
return $handle_obj;
});
$ffi->attach( [ 'DeletePRunHandle' => 'AI::TensorFlow::Libtensorflow::Session::_PRHandle::DESTROY' ] => [
arg 'opaque' => 'handle',
] => 'void' => sub {
my ($xs, $handle_obj) = @_;
my $handle = scalar_to_pointer($$$handle_obj);
$xs->( $handle );
} );
$ffi->attach( [ 'SessionPRun' => 'PRun' ] => [
arg TF_Session => 'session',
arg 'opaque' => 'handle',
# Inputs
arg TF_Output_struct_array => 'inputs',
arg TF_Tensor_array => 'input_values',
arg int => 'ninputs',
# Outputs
arg TF_Output_struct_array => 'outputs',
lib/AI/TensorFlow/Libtensorflow/Session.pm view on Meta::CPAN
$outputs, $output_v_a, $output_v_a->count,
_process_target_opers_args($target_opers),
$status,
);
@{$output_values} = @{ AI::TensorFlow::Libtensorflow::Tensor->_from_array( $output_v_a ) };
} );
$ffi->attach( [ 'SessionListDevices' => 'ListDevices' ] => [
arg TF_Session => 'session',
arg TF_Status => 'status',
] => 'TF_DeviceList');
$ffi->attach( [ 'CloseSession' => 'Close' ] =>
[ 'TF_Session',
'TF_Status',
],
=> 'void' );
$ffi->attach( [ 'DeleteSession' => '_Delete' ] => [
arg 'TF_Session' => 's',
arg 'TF_Status' => 'status',
], => 'void' );
sub DESTROY {
my ($self) = @_;
my $s = AI::TensorFlow::Libtensorflow::Status->New;
$self->Close($s);
# TODO this may not be needed with automatic Status handling
die "Could not close session" unless $s->GetCode == AI::TensorFlow::Libtensorflow::Status::OK;
lib/AI/TensorFlow/Libtensorflow/SessionOptions.pm view on Meta::CPAN
package AI::TensorFlow::Libtensorflow::SessionOptions;
# ABSTRACT: Holds options that can be passed during session creation
$AI::TensorFlow::Libtensorflow::SessionOptions::VERSION = '0.0.7';
use strict;
use warnings;
use namespace::autoclean;
use AI::TensorFlow::Libtensorflow::Lib qw(arg);;
my $ffi = AI::TensorFlow::Libtensorflow::Lib->ffi;
$ffi->mangler(AI::TensorFlow::Libtensorflow::Lib->mangler_default);
$ffi->attach( [ 'NewSessionOptions' => 'New' ] =>
[ ], => 'TF_SessionOptions' );
$ffi->attach( [ 'DeleteSessionOptions' => 'DESTROY' ] => [
arg 'TF_SessionOptions' => 'self',
] => 'void');
$ffi->attach( 'SetTarget' => [
arg 'TF_SessionOptions' => 'options',
arg 'string' => 'target',
] => 'void');
$ffi->attach( 'SetConfig' => [
arg 'TF_SessionOptions' => 'options',
arg 'tf_config_proto_buffer' => [qw(proto proto_len)],
arg 'TF_Status' => 'status',
] => 'void' );
$ffi->attach( 'EnableXLACompilation' => [
arg TF_SessionOptions => 'options',
arg 'unsigned char' => 'enable'
] => 'void' );
1;
__END__
=pod
lib/AI/TensorFlow/Libtensorflow/Status.pm view on Meta::CPAN
$ffi->load_custom_type('::Enum', 'TF_Code',
{ rev => 'int', package => __PACKAGE__ },
@_TF_CODE
);
my %_TF_CODE_INT_TO_NAME = map { reverse @$_ } @_TF_CODE;
#}}}
$ffi->attach( [ 'NewStatus' => 'New' ] => [] => 'TF_Status' );
$ffi->attach( [ 'DeleteStatus' => 'DESTROY' ] => [ 'TF_Status' ], 'void' );
$ffi->attach( 'SetStatus' => [ 'TF_Status', 'TF_Code', 'string' ], 'void' );
$ffi->attach( 'SetPayload' => [ 'TF_Status', 'string', 'string' ], 'void' );
$ffi->attach( 'SetStatusFromIOError' => [ 'TF_Status', 'int', 'string' ],
'void' );
$ffi->attach( 'GetCode' => [ 'TF_Status' ], 'TF_Code' );
$ffi->attach( 'Message' => [ 'TF_Status' ], 'string' );
use overload
'""' => \&_op_stringify;
sub _op_stringify {
$_TF_CODE_INT_TO_NAME{$_[0]->GetCode};
}
sub _data_printer {
my ($self, $ddp) = @_;
lib/AI/TensorFlow/Libtensorflow/TFLibrary.pm view on Meta::CPAN
package AI::TensorFlow::Libtensorflow::TFLibrary;
# ABSTRACT: TensorFlow dynamic library handle and ops
$AI::TensorFlow::Libtensorflow::TFLibrary::VERSION = '0.0.7';
use strict;
use warnings;
use AI::TensorFlow::Libtensorflow::Lib qw(arg);
my $ffi = AI::TensorFlow::Libtensorflow::Lib->ffi;
$ffi->attach( [ 'LoadLibrary' => 'LoadLibrary' ] => [
arg string => 'library_filename',
arg TF_Status => 'status',
] => 'TF_Library' => sub {
my ($xs, $class, @rest) = @_;
$xs->(@rest);
} );
$ffi->attach( [ 'GetOpList' => 'GetOpList' ] => [
arg TF_Library => 'lib_handle'
] => 'TF_Buffer' );
$ffi->attach( [ 'DeleteLibraryHandle' => 'DESTROY' ] => [
arg TF_Library => 'lib_handle'
] => 'void' );
$ffi->attach( 'GetAllOpList' => [], 'TF_Buffer' );
1;
__END__
=pod
=encoding UTF-8
lib/AI/TensorFlow/Libtensorflow/TString.pm view on Meta::CPAN
# TF_TSTR_VIEW = 0x03,
# TF_TSTR_TYPE_MASK = 0x03
# } TF_TString_Type;
sub _CREATE {
my ($class) = @_;
my $pointer = malloc SIZEOF_TF_TString;
my $obj = bless { ptr => $pointer }, $class;
}
$ffi->attach( [ 'StringInit' => 'Init' ] => [
arg 'TF_TString' => 'tstr'
] => 'void' => sub {
my ($xs, $invoc) = @_;
my $obj = ref $invoc ? $invoc : $invoc->_CREATE();
$xs->($obj);
$obj;
});
$ffi->attach( [ 'StringCopy' => 'Copy' ] => [
arg TF_TString => 'dst',
arg tf_text_buffer => [ qw( src size ) ],
] => 'void' );
$ffi->attach( [ 'StringAssignView' => 'AssignView' ] => [
arg TF_TString => 'dst',
arg tf_text_buffer => [ qw( src size ) ],
] => 'void' );
$ffi->attach( [ 'StringGetDataPointer' => 'GetDataPointer' ] => [
arg TF_TString => 'tstr',
] => 'opaque' );
$ffi->attach( [ 'StringGetType' => 'GetType' ] => [
arg TF_TString => 'str'
] => 'int' );
$ffi->attach( [ 'StringGetSize' => 'GetSize' ] => [
arg TF_TString => 'tstr'
] => 'size_t' );
$ffi->attach( [ 'StringGetCapacity' => 'GetCapacity' ] => [
arg TF_TString => 'str'
] => 'size_t' );
$ffi->attach( [ 'StringDealloc' => 'Dealloc' ] => [
arg TF_TString => 'tstr',
] => 'void' );
sub DESTROY {
if( ! $_[0]->{owner} ) {
$_[0]->Dealloc;
free $_[0]->{ptr};
}
}
lib/AI/TensorFlow/Libtensorflow/Tensor.pm view on Meta::CPAN
my $ffi = AI::TensorFlow::Libtensorflow::Lib->ffi;
$ffi->mangler(AI::TensorFlow::Libtensorflow::Lib->mangler_default);
$ffi->load_custom_type('AI::TensorFlow::Libtensorflow::Lib::FFIType::TFPtrSizeScalarRef'
=> 'tf_tensor_buffer'
);
$ffi->attach( [ 'NewTensor' => 'New' ] =>
[
arg 'TF_DataType' => 'dtype',
# const int64_t* dims, int num_dims
arg 'tf_dims_buffer' => [ qw(dims num_dims) ],
# void* data, size_t len
arg 'tf_tensor_buffer' => [ qw(data len) ],
arg 'opaque' => 'deallocator', # tensor_deallocator_t (deallocator)
lib/AI/TensorFlow/Libtensorflow/Tensor.pm view on Meta::CPAN
$obj->{_deallocator_closure} = $deallocator_closure;
$obj;
});
# C: TF_AllocateTensor
#
# Constructor
$ffi->attach( [ 'AllocateTensor', 'Allocate' ],
[
arg 'TF_DataType' => 'dtype',
arg 'tf_dims_buffer' => [ qw(dims num_dims) ],
arg 'size_t' => 'len',
],
=> 'TF_Tensor' => sub {
my ($xs, $class, @rest) = @_;
my ($dtype, $dims, $len) = @rest;
if( ! defined $len ) {
$len = product($dtype->Size, @$dims);
}
my $obj = $xs->($dtype, $dims, $len);
}
);
$ffi->attach( [ 'DeleteTensor' => 'DESTROY' ],
[ arg 'TF_Tensor' => 't' ]
=> 'void'
=> sub {
my ($xs, $self) = @_;
$xs->($self);
if( exists $self->{_deallocator_closure} ) {
$self->{_deallocator_closure}->unstick;
}
}
);
$ffi->attach( [ 'TensorData' => 'Data' ],
[ arg 'TF_Tensor' => 'self' ],
=> 'opaque'
=> sub {
my ($xs, @rest) = @_;
my ($self) = @rest;
my $data_p = $xs->(@rest);
window(my $buffer, $data_p, $self->ByteSize);
\$buffer;
}
);
$ffi->attach( [ 'TensorByteSize' => 'ByteSize' ],
[ arg 'TF_Tensor' => 'self' ],
=> 'size_t'
);
$ffi->attach( [ 'TensorType' => 'Type' ],
[ arg 'TF_Tensor' => 'self' ],
=> 'TF_DataType'
);
$ffi->attach( [ 'NumDims' => 'NumDims' ],
[ arg 'TF_Tensor' => 'self' ],
=> 'int',
);
$ffi->attach( [ 'TensorElementCount' => 'ElementCount' ] =>
[ arg 'TF_Tensor' => 'self' ]
=> 'int64_t'
);
$ffi->attach( [ 'Dim' => 'Dim' ],
[
arg 'TF_Tensor' => 't',
arg 'int' => 'dim_index',
],
=> 'int64_t',
);
$ffi->attach( [ 'TensorMaybeMove' => 'MaybeMove' ] =>
[ arg 'TF_Tensor' => 'self' ],
=> 'TF_Tensor',
);
$ffi->attach( ['TensorIsAligned' => 'IsAligned'] => [
arg TF_Tensor => 't'
] => 'bool' );
eval {# TF v2.10.0
$ffi->attach( [ 'SetShape' => 'SetShape' ] =>
[
arg 'TF_Tensor' => 'self',
arg 'tf_dims_buffer' => [ qw(dims num_dims) ],
]
=> 'void'
);
};
$ffi->attach( [ 'TensorBitcastFrom' => 'BitcastFrom' ] => [
arg TF_Tensor => 'from',
arg TF_DataType => 'type',
arg TF_Tensor => 'to',
arg 'tf_dims_buffer' => [ qw(new_dims num_new_dims) ],
arg TF_Status => 'status',
] => 'void' );
#### Array helpers ####
use FFI::C::ArrayDef;
use FFI::C::StructDef;
lib/AI/TensorFlow/Libtensorflow/_Misc.pm view on Meta::CPAN
# ABSTRACT: Private API
$AI::TensorFlow::Libtensorflow::_Misc::VERSION = '0.0.7';
use strict;
use warnings;
use namespace::autoclean;
use AI::TensorFlow::Libtensorflow::Lib qw(arg);
my $ffi = AI::TensorFlow::Libtensorflow::Lib->ffi;
$ffi->mangler(AI::TensorFlow::Libtensorflow::Lib->mangler_default);
$ffi->attach( 'TensorFromProto' => [
arg 'TF_Buffer' => 'from',
arg 'TF_Tensor' => 'to',
arg 'TF_Status' => 'status',
]);
1;
__END__
maint/process-capi.pl view on Meta::CPAN
method check_types() {
my @data = $self->typedef_struct_data->@*;
my %types = map { $_ => 1 } AI::TensorFlow::Libtensorflow::Lib->ffi->types;
my %part;
@part{qw(todo done)} = part { exists $types{$_} } uniq map { $_->{name} } @data;
use DDP; p %part;
}
method check_functions($first_arg = undef) {
my $functions = AI::TensorFlow::Libtensorflow::Lib->ffi->_attached_functions;
my @dupes = map { $_->[0]{c} }
grep { @$_ != 1 } values $functions->%*;
die "Duplicated functions @dupes" if @dupes;
my @data = $self->fdecl_data->@*;
say <<~STATS;
Statistics:
==========
Attached functions: @{[ scalar keys %$functions ]}
maint/process-capi.pl view on Meta::CPAN
load 'AI::TensorFlow::Libtensorflow::_Misc';
}
}
package AttachedFunctionTrackable {
use Mu::Role;
use Sub::Uplevel qw(uplevel);
use Hook::LexWrap;
ro _attached_functions => ( default => sub { {} } );
around attach => sub {
my ($orig, $self, $name) = @_;
my $real_name;
wrap 'FFI::Platypus::DL::dlsym',
post => sub { $real_name = $_[1] if $_[-1] };
my $ret = uplevel 3, $orig, @_[1..$#_];
push $self->_attached_functions->{$real_name}->@*, {
c => $real_name,
package => (caller(2))[0],
perl => ref($name) ? $name->[1] : $name,
args => $_[3],
return => $_[4],
};
$ret;
}
}