--- OpenCL/OpenCL.pm 2012/04/21 20:48:03 1.49 +++ OpenCL/OpenCL.pm 2012/04/24 14:30:57 1.53 @@ -159,12 +159,7 @@ } '; - my $prog = $ctx->program_with_source ($src); - - # build croaks on compile errors, so catch it and print the compile errors - eval { $prog->build ($dev, "-cl-fast-relaxed-math"); 1 } - or die $prog->build_log; - + my $prog = $ctx->build_program ($src); my $kernel = $prog->kernel ("squareit"); =head2 Create some input and output float buffers, then call the @@ -269,10 +264,8 @@ write_imagef (img, (int2)(get_global_id (0), get_global_id (1)), (float4)(colour * p.x * p.x, 1.)); } EOF - my $prog = $ctx->program_with_source ($src); - eval { $prog->build ($dev); 1 } - or die $prog->build_log ($dev); + my $prog = $ctx->build_program ($src); my $kernel = $prog->kernel ("juliatunnel"); # program compiled, kernel ready, now draw and loop @@ -385,6 +378,43 @@ have been created and be made current, and C must be available and capable of finding the function via C. +=cut + +package OpenCL; + +use common::sense; + +BEGIN { + our $VERSION = '0.96'; + + require XSLoader; + XSLoader::load (__PACKAGE__, $VERSION); + + @OpenCL::Platform::ISA = + @OpenCL::Device::ISA = + @OpenCL::Context::ISA = + @OpenCL::Queue::ISA = + @OpenCL::Memory::ISA = + @OpenCL::Sampler::ISA = + @OpenCL::Program::ISA = + @OpenCL::Kernel::ISA = + @OpenCL::Event::ISA = OpenCL::Object::; + + @OpenCL::Buffer::ISA = + @OpenCL::Image::ISA = OpenCL::Memory::; + + @OpenCL::BufferObj::ISA = OpenCL::Buffer::; + + @OpenCL::Image2D::ISA = + @OpenCL::Image3D::ISA = + @OpenCL::Image2DArray::ISA = + @OpenCL::Image1D::ISA = + @OpenCL::Image1DArray::ISA = + @OpenCL::Image1DBuffer::ISA = OpenCL::Image::; + + @OpenCL::UserEvent::ISA = OpenCL::Event::; +} + =head2 THE OpenCL PACKAGE =over 4 @@ -426,6 +456,29 @@ =back +=head2 THE OpenCL::Object CLASS + +This is the base class for all objects in the OpenCL module. The only +method it implements is the C method, which is only useful if you want +to interface to OpenCL on the C level. + +=over 4 + +=item $iv = $obj->id + +OpenCL objects are represented by pointers or integers on the C level. If +you want to interface to an OpenCL object directly on the C level, then +you need this value, which is returned by this method. You should use an +C type in your code and cast that to the correct type. + +=cut + +sub OpenCL::Object::id { + ${$_[0]} +} + +=back + =head2 THE OpenCL::Platform CLASS =over 4 @@ -458,6 +511,13 @@ L +=item $platform->unload_compiler + +Attempts to unload the compiler for this platform, for endless +profit. Does nothing on OpenCL 1.1. + +L + =for gengetinfo begin platform =item $string = $platform->profile @@ -768,6 +828,33 @@ =over 4 +=item $prog = $ctx->build_program ($program, $options = "") + +This convenience function tries to build the program on all devices in +the context. If the build fails, then the function will C with the +build log. Otherwise ti returns the program object. + +The C<$program> can either be a C object or a string +containing the program. In the latter case, a program objetc will be +created automatically. + +=cut + +sub OpenCL::Context::build_program { + my ($self, $prog, $options) = @_; + + $prog = $self->program_with_source ($prog) + unless ref $prog; + + for my $dev ($self->devices) { + eval { $prog->build ($dev, $options); 1 } + or Carp::croak "Building OpenCL program for device '" . $dev->name . "' failed:\n" + . $prog->build_log ($dev); + } + + $prog +} + =item $queue = $ctx->queue ($device, $properties) Create a new OpenCL::Queue object from the context and the given device. @@ -975,6 +1062,22 @@ L. +=item $ev = $queue->enqueue_fill_buffer ($mem, $pattern, $offset, $size, ...) + +Fills the given buffer object with repeated applications of C<$pattern>, +starting at C<$offset> for C<$size> octets. + +L + +=item $ev = $queue->enqueue_fill_image ($img, $r, $g, $b, $a, $x, $y, $z, $width, $height, $depth, ...) + +Fills the given image area with the given rgba colour components. The +components are normally floating point values between C<0> and C<1>, +except when the image channel data type is a signe dor unsigned +unnormalised format, in which case the range is determined by the format. + +L + =item $ev = $queue->enqueue_task ($kernel, $wait_events...) L @@ -1152,7 +1255,7 @@ =over 4 -=item $packed_value = $ev->image_info ($name) +=item $packed_value = $image->image_info ($name) See C<< $platform->info >> for details. @@ -1161,6 +1264,11 @@ L +=item ($channel_order, $channel_data_type) = $image->format + +Returns the channel order and type used to create the image by calling +C with C. + =for gengetinfo begin image =item $int = $image->element_size @@ -1245,7 +1353,8 @@ =item $program->build ($device, $options = "") -Tries to build the program with the givne options. +Tries to build the program with the given options. See also the +C<$ctx->build> convenience function. L @@ -1263,6 +1372,12 @@ L +=item @kernels = $program->kernels_in_program + +Returns all kernels successfully compiled for all devices in program. + +http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clCreateKernelsInProgram.html + =for gengetinfo begin program_build =item $build_status = $program->build_status ($device) @@ -1407,6 +1522,10 @@ set by specifying the size, and sampler and event must be objects of that type. +Setting an argument for a kernel does NOT keep a reference to the object - +for example, if you set an argument to some image object, free the image, +and call the kernel, you will run into undefined behaviour. + L =back @@ -1499,31 +1618,6 @@ =cut -package OpenCL; - -use common::sense; - -BEGIN { - our $VERSION = '0.96'; - - require XSLoader; - XSLoader::load (__PACKAGE__, $VERSION); - - @OpenCL::Buffer::ISA = - @OpenCL::Image::ISA = OpenCL::Memory::; - - @OpenCL::BufferObj::ISA = OpenCL::Buffer::; - - @OpenCL::Image2D::ISA = - @OpenCL::Image3D::ISA = - @OpenCL::Image2DArray::ISA = - @OpenCL::Image1D::ISA = - @OpenCL::Image1DArray::ISA = - @OpenCL::Image1DBuffer::ISA = OpenCL::Image::; - - @OpenCL::UserEvent::ISA = OpenCL::Event::; -} - 1; =head1 AUTHOR