class CAIterator


carray/iterator.rb

This file is part of Ruby/CArray extension library.

Copyright (C) 2005-2020 Hiroki Motoyoshi

Public Class Methods

define_calculate_method(data_type, name) click to toggle source
# File lib/carray/iterator.rb, line 62
def self.define_calculate_method (data_type, name)
  define_method(name) { |*args|
    _data_type = data_type || self.reference.data_type
    self.calculate(_data_type, name, *args) 
  }
end
define_evaluate_method(name) click to toggle source
# File lib/carray/iterator.rb, line 15
def self.define_evaluate_method (name)
  define_method(name) { |*args|
    self.evaluate(name, *args) 
  }
end
define_filter_method(data_type, name) click to toggle source
# File lib/carray/iterator.rb, line 38
def self.define_filter_method (data_type, name)
  define_method(name) { |*args|
    _data_type = data_type || self.reference.data_type
    self.filter(_data_type, name, *args) 
  }
end

Public Instance Methods

[](*idx) click to toggle source
# File lib/carray/iterator.rb, line 141
def [] (*idx)
  if idx.any?{|x| x.is_a?(Symbol) }
    return ca[*idx]
  else
    case idx.size
    when 0
      return clone
    when 1
      return kernel_at_addr(idx[0])
    else
      return kernel_at_index(idx)
    end
  end
end
[]=(*idx) click to toggle source
# File lib/carray/iterator.rb, line 156
def []= (*idx)
  val = idx.pop
  if idx.any?{|x| x.is_a?(Symbol) }
    ca[*idx] = [val]
  else
    case idx.size
    when 0
      asign!(val)
    when 1
      kernel_at_addr(idx[0])[] = val
    else
      kernel_at_index(idx)[] = val
    end
  end
end
asign!(val) click to toggle source
# File lib/carray/iterator.rb, line 134
def asign! (val)
  each do |elem|
    elem[] = val
  end
  return self
end
ca() click to toggle source

# File lib/carray/iterator.rb, line 116
def ca
  @iterary ||= CAIteratorArray.new(self)
  return @iterary
end
calculate(*args) click to toggle source
yard:

class CAIterator

def calculate
end

end

VALUE
rb_ca_iter_calculate (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE rtype, rbytes, routput, rref, rker, rout;
  CArray *co, *cr, *ck;
  ca_size_t elements;
  int8_t data_type;
  ca_size_t bytes;
  int i;

  if ( argc < 1 ) {
    rb_raise(rb_eArgError, "invalid # of arguments");
  }

  elements = ca_iter_elements(self);

  rref     = ca_iter_reference(self);
  Data_Get_Struct(rref, CArray, cr);
  
  if ( NIL_P(argv[0]) ) {
    rtype = INT2NUM(cr->data_type);
    rbytes = SIZE2NUM(cr->bytes);
  }
  else {
    rb_ca_guess_type_and_bytes(argv[0], Qnil, &data_type, &bytes);
    rtype = INT2NUM(data_type);
    rbytes = SIZE2NUM(bytes);
  }
  argc--;
  argv++;

  routput = ca_iter_prepare_output(self, rtype, rbytes);
  Data_Get_Struct(routput, CArray, co);

  ca_attach(cr);

  if ( rb_const_get(CLASS_OF(self), rb_intern("UNIFORM_KERNEL")) ) {

    rker = ca_iter_kernel_at_addr(self, 0, rref);

    Data_Get_Struct(rker, CArray, ck);
    ca_attach(ck);

    if ( rb_block_given_p() ) {
      for (i=0; i<elements; i++) {
        ca_iter_kernel_move_to_addr(self, i, rker);
        ca_update(ck);
        rout = rb_yield(rker);
        rb_ca_store_addr(routput, i, rout);
      }
    }
    else {
      if ( argc < 1 ) {
        rb_raise(rb_eArgError, "invalid # of arguments");
      }
      for (i=0; i<elements; i++) {
        ca_iter_kernel_move_to_addr(self, i, rker);
        ca_update(ck);
        rout = rb_funcall2(rker, SYM2ID(argv[0]), argc-1, &argv[1]);
        rb_ca_store_addr(routput, i, rout);
      }
    }

    ca_detach(ck);
  }
  else {
    
    if ( rb_block_given_p() ) {
      for (i=0; i<elements; i++) {
        rker = ca_iter_kernel_at_addr(self, i, rref);
        rout = rb_yield(rker);
        rb_ca_store_addr(routput, i, rout);
      }
    }
    else {
      if ( argc < 1 ) {
        rb_raise(rb_eArgError, "invalid # of arguments");
      }
      for (i=0; i<elements; i++) {
        rker = ca_iter_kernel_at_addr(self, i, rref);
        rout = rb_funcall2(rker, SYM2ID(argv[0]), argc-1, &argv[1]);
        rb_ca_store_addr(routput, i, rout);
      }
    }
    
  }

  ca_detach(cr);

  return routput;
}
convert(data_type, options={}) { |clone| ... } click to toggle source
# File lib/carray/iterator.rb, line 181
def convert (data_type, options={})
  out = prepare_output(data_type, options)
  out.map_addr!{ |addr|
    blk = kernel_at_addr(addr)
    yield(blk.clone)
  }
  return out
end
dim() click to toggle source
yard:

class CAIterator

def dim
end

end

VALUE
rb_ca_iter_dim (VALUE self)
{
  VALUE rdim;
  ca_size_t dim[CA_RANK_MAX];
  int8_t ndim = ca_iter_ndim(self);
  int i;
  ca_iter_dim(self, dim);
  rdim = rb_ary_new2(ndim);
  for (i=0; i<ndim; i++) {
    rb_ary_store(rdim, i, SIZE2NUM(dim[i]));
  }
  return rdim;
}
Also aliased as: shape
each() { |clone| ... } click to toggle source
# File lib/carray/iterator.rb, line 190
def each ()
  retval = nil
  if self.class::UNIFORM_KERNEL
    reference.attach! {
      blk = kernel_at_addr(0)
      elements.times do |addr|
        kernel_move_to_addr(addr, blk)
        retval = yield(blk.clone)
      end
    }
  else
    elements.times do |addr|
      retval = yield(kernel_at_addr(addr).clone)
    end
  end
  return retval
end
each_with_addr() { |clone, addr| ... } click to toggle source
# File lib/carray/iterator.rb, line 208
def each_with_addr ()
  retval = nil
  if self.class::UNIFORM_KERNEL
    reference.attach! {
      elements.times do |addr|
        blk = kernel_at_addr(addr)
        retval = yield(blk.clone, addr)
      end
    }
  else
    elements.times do |addr|
      retval = yield(kernel_at_addr(addr).clone, addr)
    end
  end
  return retval
end
each_with_index() { |clone, idx| ... } click to toggle source
# File lib/carray/iterator.rb, line 225
def each_with_index ()
  retval = nil
  if self.class::UNIFORM_KERNEL
    reference.attach! {
      CArray.each_index(*dim) do |*idx|
        blk = kernel_at_index(idx)
        retval = yield(blk.clone, idx)
      end
    }
  else
    CArray.each_index(*dim) do |*idx|
      retval = yield(kernel_at_index(idx).clone, idx)
    end
  end
  return retval
end
elements() click to toggle source
yard:

class CAIterator

def elements
end

end

VALUE
rb_ca_iter_elements (VALUE self)
{
  return SIZE2NUM(ca_iter_elements(self));
}
evaluate(*args) click to toggle source
yard:

class CAIterator

def evaluate
end

end

VALUE
rb_ca_iter_evaluate (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE rref, rker;
  CArray *cr, *ck;
  ca_size_t elements;
  int i;

  elements = ca_iter_elements(self);
  rref  = ca_iter_reference(self);

  Data_Get_Struct(rref, CArray, cr);

  ca_attach(cr);

  if ( rb_const_get(CLASS_OF(self), rb_intern("UNIFORM_KERNEL")) ) {

    rker = ca_iter_kernel_at_addr(self, 0, rref);

    Data_Get_Struct(rker, CArray, ck);

    ca_attach(ck);

    for (i=0; i<elements; i++) {
      ca_iter_kernel_move_to_addr(self, i, rker);
      ca_update(ck);
      rb_funcall2(rker, SYM2ID(argv[0]), argc-1, &argv[1]);
    }

    ca_detach(ck);
  }
  else {    

    for (i=0; i<elements; i++) {
      rker = ca_iter_kernel_at_addr(self, i, rref);
      rb_funcall2(rker, SYM2ID(argv[0]), argc-1, &argv[1]);
    }

  }

  ca_sync(cr);
  ca_detach(cr);

  return self;
}
filter(*args) click to toggle source
yard:

class CAIterator

def filter
end

end

VALUE
rb_ca_iter_filter (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE routput, rref, rker, rout;
  CArray *co, *cr, *ck, *cq;
  ca_size_t elements;
  int8_t data_type;
  int i;

  if ( argc < 2 ) {
    rb_raise(rb_eArgError, "invalid # of arguments");
  }

  elements = ca_iter_elements(self);
  rref = ca_iter_reference(self);

  Data_Get_Struct(rref, CArray, cr);

  /* FIXME: check data_type validity */

  data_type = NIL_P(argv[0]) ? cr->data_type : rb_ca_guess_type(argv[0]);
  argc--;
  argv++;

  co = carray_new(data_type, cr->ndim, cr->dim, 0, NULL);
  routput = ca_wrap_struct(co);

  if ( NIL_P(argv[0]) ) {
    rb_ca_data_type_inherit(routput, rref);
  }

  ca_attach(cr);

  if ( rb_const_get(CLASS_OF(self), rb_intern("UNIFORM_KERNEL")) ) {

    rker = ca_iter_kernel_at_addr(self, 0, rref);
    Data_Get_Struct(rker, CArray, ck);
    ca_allocate(ck);

    rout = ca_iter_kernel_at_addr(self, 0, routput);
    Data_Get_Struct(rker, CArray, cq);
    ca_allocate(cq);

    for (i=0; i<elements; i++) {
      ca_iter_kernel_move_to_addr(self, i, rker);
      ca_iter_kernel_move_to_addr(self, i, rout);
      ca_update(ck);
      rb_funcall(rout, rb_intern("[]="), 1,
        rb_funcall2(rker, SYM2ID(argv[0]), argc-1, &argv[1]));
      ca_sync(cq);
    }

    ca_detach_n(2, ck, cq);

  }
  else {

    for (i=0; i<elements; i++) {
      rker = ca_iter_kernel_at_addr(self, i, rref);
      rout = ca_iter_kernel_at_addr(self, i, routput);
      rb_funcall(rout, rb_intern("[]="), 1,
        rb_funcall2(rker, SYM2ID(argv[0]), argc-1, &argv[1]));
    }

  }

  ca_detach(cr);
  return routput;
}
inject(*argv) { |memo, val| ... } click to toggle source
# File lib/carray/iterator.rb, line 242
def inject (*argv)
  case argv.size
  when 0
    memo = nil
    each_with_addr do |val, addr|
      if addr == 0
        memo = val
      else
        memo = yield(memo, val)
      end
    end
    return memo
  when 1
    memo = argv.first
    each do |val|
      memo = yield(memo, val)
    end
    return memo
  else
    raise "invalid number of arguments (#{argv.size} for 0 or 1)"
  end
end
kernel_at_addr(p1, p2 = v2) click to toggle source
yard:

class CAIterator

def kernel_at_addr
end

end

VALUE
rb_ca_iter_kernel_at_addr (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE raddr, rcarray;
  rb_scan_args(argc, argv, "11", (VALUE *) &raddr, (VALUE *) &rcarray);
  if ( NIL_P(rcarray) ) {
    rcarray = rb_ca_iter_reference(self);
  }
  return ca_iter_kernel_at_addr(self, NUM2SIZE(raddr), rcarray);
}
kernel_at_index(p1, p2 = v2) click to toggle source
yard:

class CAIterator

def kernel_at_index
end

end

VALUE
rb_ca_iter_kernel_at_index (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE rindex, rcarray;
  ca_size_t idx[CA_RANK_MAX];
  int8_t  ndim = ca_iter_ndim(self);
  int i;

  rb_scan_args(argc, argv, "11", (VALUE *) &rindex, (VALUE *) &rcarray);

  if ( NIL_P(rcarray) ) {
    rcarray = rb_ca_iter_reference(self);
  }

  for (i=0; i<ndim; i++) {
    idx[i] = NUM2SIZE(rb_ary_entry(rindex, i));
  }

  return ca_iter_kernel_at_index(self, idx, rcarray);
}
kernel_move_to_addr(p1, p2) click to toggle source
yard:

class CAIterator

def kernel_move_to_addr
end

end

VALUE
rb_ca_iter_kernel_move_to_addr (VALUE self, VALUE raddr, VALUE rker)
{
  return ca_iter_kernel_move_to_addr(self, NUM2SIZE(raddr), rker);
}
kernel_move_to_index(p1, p2) click to toggle source
yard:

class CAIterator

def kernel_move_to_index
end

end

VALUE
rb_ca_iter_kernel_move_to_index (VALUE self, VALUE rindex, VALUE rker)
{
  ca_size_t idx[CA_RANK_MAX];
  int8_t  ndim = ca_iter_ndim(self);
  int i;

  for (i=0; i<ndim; i++) {
    idx[i] = NUM2SIZE(rb_ary_entry(rindex, i));
  }

  return ca_iter_kernel_move_to_index(self, idx, rker);
}
ndim() click to toggle source
yard:

class CAIterator

def ndim
end

end

VALUE
rb_ca_iter_ndim (VALUE self)
{
  return LONG2NUM(ca_iter_ndim(self));
}
Also aliased as: rank
pick(*idx) click to toggle source
# File lib/carray/iterator.rb, line 125
def pick (*idx)
  out = prepare_output(reference.data_type, :bytes=>reference.bytes)
  elements.times do |addr|
    blk = kernel_at_addr(addr)
    out[addr] = blk[*idx]
  end
  return out
end
prepare_output(p1, p2 = v2) click to toggle source
yard:

class CAIterator

def prepare_output
end

end

VALUE
rb_ca_iter_prepare_output (int argc, VALUE *argv, VALUE self)
{
  VALUE rtype, ropt, rbytes = Qnil;

  rb_scan_args(argc, argv, "11", &rtype, &ropt);
  rb_scan_options(ropt, "bytes", &rbytes);

  return ca_iter_prepare_output(self, rtype, rbytes);
}
put(*idx) click to toggle source
# File lib/carray/iterator.rb, line 172
def put (*idx)
  val = idx.pop
  elements.times do |addr|
    blk = kernel_at_addr(addr)
    blk[*idx] = val
  end
  return self
end
rank()
yard:

class CAIterator

def ndim
end

end

Alias for: ndim
reference() click to toggle source
yard:

class CAIterator

def reference
end

end

VALUE
rb_ca_iter_reference (VALUE self)
{
  return ca_iter_reference(self);
}
shape()
yard:

class CAIterator

def dim
end

end

Alias for: dim
sort_by(&block) click to toggle source
# File lib/carray/iterator.rb, line 271
def sort_by (&block)
  out = reference.template
  idx = ca.convert(:object, &block).sort_addr
  ca[idx].each_with_addr do |blk, i|
    kernel_at_addr(i, out)[] = blk
  end
  return out
end
sort_by!(&block) click to toggle source
# File lib/carray/iterator.rb, line 265
def sort_by! (&block)
  ia = self.ca
  ia[] = ia.to_a.sort_by(&block).map{|x| x.to_ca }
  return reference
end
sort_with() { |self| ... } click to toggle source
# File lib/carray/iterator.rb, line 280
def sort_with (&block)
  warn "CAIterator#sort_with will be obsolete"
  out = reference.template
  idx = CA.sort_addr(*yield(self))
  ca[idx].each_with_addr do |blk, i|
    kernel_at_addr(i, out)[] = blk
  end
  return out
end
to_a() click to toggle source
# File lib/carray/iterator.rb, line 121
def to_a
  return ca.to_a
end