AI-TensorFlow-Libtensorflow

 view release on metacpan or  search on metacpan

lib/AI/TensorFlow/Libtensorflow/Tensor.pm  view on Meta::CPAN

package AI::TensorFlow::Libtensorflow::Tensor;
# ABSTRACT: A multi-dimensional array of elements of a single data type
$AI::TensorFlow::Libtensorflow::Tensor::VERSION = '0.0.7';
use strict;
use warnings;
use namespace::autoclean;
use AI::TensorFlow::Libtensorflow::Lib qw(arg);
use FFI::Platypus::Closure;
use FFI::Platypus::Buffer qw(window);
use List::Util qw(product);

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)
		arg 'opaque'      => 'deallocator_arg',
	],
	=> 'TF_Tensor' => sub {
		my ($xs, $class,
			$dtype, $dims, $data,
			$deallocator, $deallocator_arg,
		) = @_;
		my $deallocator_closure = $ffi->closure( $deallocator );
		$deallocator_closure->sticky;
		my $deallocator_ptr = $ffi->cast(
			'tensor_deallocator_t', 'opaque',
			$deallocator_closure );

		my $obj = $xs->(
			$dtype,
			$dims,
			$data,
			$deallocator_ptr, $deallocator_arg,
		);

		# Return early if no TF_Tensor created
		# TODO should this throw an exception instead?
		return unless $obj;

		$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;

lib/AI/TensorFlow/Libtensorflow/Tensor.pm  view on Meta::CPAN


=head1 CONSTRUCTORS

=head2 New

=over 2

C<<<
New( $dtype, $dims, $data, $deallocator, $deallocator_arg )
>>>

=back

Creates a C<TFTensor> from a data buffer C<$data> with the given specification
of data type C<$dtype> and dimensions C<$dims>.

  # Create a buffer containing 0 through 8 single-precision
  # floating-point data.
  my $data = pack("f*",  0..8);

  $t = Tensor->New(
    FLOAT, [3,3], \$data, sub { undef $data }, undef
  );

  ok $t, 'Created 3-by-3 float TFTensor';

Implementation note: if C<$dtype> is not a
L<STRING|AI::TensorFlow::Libtensorflow::DataType/STRING>
or
L<RESOURCE|AI::TensorFlow::Libtensorflow::DataType/RESOURCE>,
then the pointer for C<$data> is checked to see if meets the
TensorFlow's alignment preferences. If it does not, the
contents of C<$data> are copied into a new buffer and
C<$deallocator> is called during construction.
Otherwise the contents of C<$data> are not owned by the returned
C<TFTensor>.

B<Parameters>

=over 4

=item L<TFDataType|AI::TensorFlow::Libtensorflow::Lib::Types/TFDataType> $dtype

DataType for the C<TFTensor>.

=item L<Dims|AI::TensorFlow::Libtensorflow::Lib::Types/Dims> $dims

An C<ArrayRef> of the size of each dimension.

=item ScalarRef[Bytes] $data

Data buffer for the contents of the C<TFTensor>.

=item CodeRef $deallocator

A callback used to deallocate C<$data> which is passed the
parameters C<<
  $deallocator->( opaque $pointer, size_t $size, opaque $deallocator_arg)
>>.

=item Ref $deallocator_arg [optional, default: C<undef>]

Argument that is passed to the C<$deallocator> callback.

=back

B<Returns>

=over 4

=item L<TFTensor|AI::TensorFlow::Libtensorflow::Lib::Types/TFTensor>

A new C<TFTensor> with the given data and specification.

=back

B<C API>: L<< C<TF_NewTensor>|AI::TensorFlow::Libtensorflow::Manual::CAPI/TF_NewTensor >>

=head2 Allocate

=over 2

C<<<
Allocate($dtype, $dims, $len = )
>>>

=back

This constructs a C<TFTensor> with the memory for the C<TFTensor>
allocated and owned by the C<TFTensor> itself. Unlike with L</New>
the allocated memory satisfies TensorFlow's alignment preferences.

See L</Data> for how to write to the data buffer.

  use AI::TensorFlow::Libtensorflow::DataType qw(DOUBLE);

  # Allocate a 2-by-2 ndarray of type DOUBLE
  $dims = [2,2];
  my $t = Tensor->Allocate(DOUBLE, $dims, product(DOUBLE->Size, @$dims));

B<Parameters>

=over 4

=item L<TFDataType|AI::TensorFlow::Libtensorflow::Lib::Types/TFDataType> $dtype

DataType for the C<TFTensor>.

=item L<Dims|AI::TensorFlow::Libtensorflow::Lib::Types/Dims> $dims

An C<ArrayRef> of the size of each dimension.

=item size_t $len [optional]

Number of bytes for the data buffer. If a value is not given,
this is calculated from C<$dtype> and C<$dims>.

=back

B<Returns>



( run in 0.631 second using v1.01-cache-2.11-cpan-140bd7fdf52 )