Class: CAIterator

Inherits:
Object show all
Includes:
Enumerable
Defined in:
lib/carray/iterator.rb,
ext/carray_iterator.c

Overview


carray/iterator.rb

This file is part of Ruby/CArray extension library.
You can redistribute it and/or modify it under the terms of
the Ruby Licence.

Copyright (C) 2005 Hiroki Motoyoshi

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.define_calculate_method(data_type, name) ⇒ Object



64
65
66
67
68
69
# File 'lib/carray/iterator.rb', line 64

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) ⇒ Object



17
18
19
20
21
# File 'lib/carray/iterator.rb', line 17

def self.define_evaluate_method (name)
  define_method(name) { |*args|
    self.evaluate(name, *args) 
  }
end

.define_filter_method(data_type, name) ⇒ Object



40
41
42
43
44
45
# File 'lib/carray/iterator.rb', line 40

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

Instance Method Details

#[](*idx) ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/carray/iterator.rb', line 143

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) ⇒ Object



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/carray/iterator.rb', line 158

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) ⇒ Object



136
137
138
139
140
141
# File 'lib/carray/iterator.rb', line 136

def asign! (val)
  each do |elem|
    elem[] = val
  end
  return self
end

#caObject




118
119
120
121
# File 'lib/carray/iterator.rb', line 118

def ca
  @iterary ||= CAIteratorArray.new(self)
  return @iterary
end

#calculateObject

yard:

class CAIterator
  def calculate
  end
end


379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
# File 'ext/carray_iterator.c', line 379

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 = {}) ⇒ Object



183
184
185
186
187
188
189
190
# File 'lib/carray/iterator.rb', line 183

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

#dimObject

yard:

class CAIterator
  def dim
  end
end


231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'ext/carray_iterator.c', line 231

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

#eachObject



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/carray/iterator.rb', line 192

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_addrObject



210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/carray/iterator.rb', line 210

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_indexObject



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/carray/iterator.rb', line 227

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

#elementsObject

yard:

class CAIterator
  def elements
  end
end


253
254
255
256
257
# File 'ext/carray_iterator.c', line 253

VALUE
rb_ca_iter_elements (VALUE self)
{
  return SIZE2NUM(ca_iter_elements(self));
}

#evaluateObject

yard:

class CAIterator
  def evaluate
  end
end


555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
# File 'ext/carray_iterator.c', line 555

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

#filterObject

yard:

class CAIterator
  def filter
  end
end


478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
# File 'ext/carray_iterator.c', line 478

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) ⇒ Object



244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/carray/iterator.rb', line 244

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_addrObject

yard:

class CAIterator
  def kernel_at_addr
  end
end


279
280
281
282
283
284
285
286
287
288
# File 'ext/carray_iterator.c', line 279

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_indexObject

yard:

class CAIterator
  def kernel_at_index
  end
end


297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
# File 'ext/carray_iterator.c', line 297

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_addrObject

yard:

class CAIterator
  def kernel_move_to_addr
  end
end


325
326
327
328
329
# File 'ext/carray_iterator.c', line 325

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_indexObject

yard:

class CAIterator
  def kernel_move_to_index
  end
end


338
339
340
341
342
343
344
345
346
347
348
349
350
# File 'ext/carray_iterator.c', line 338

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);
}

#ndimObject

yard:

class CAIterator
  def ndim
  end
end


218
219
220
221
222
# File 'ext/carray_iterator.c', line 218

VALUE
rb_ca_iter_ndim (VALUE self)
{
  return LONG2NUM(ca_iter_ndim(self));
}

#pick(*idx) ⇒ Object



127
128
129
130
131
132
133
134
# File 'lib/carray/iterator.rb', line 127

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_outputObject

yard:

class CAIterator
  def prepare_output
  end
end


359
360
361
362
363
364
365
366
367
368
# File 'ext/carray_iterator.c', line 359

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) ⇒ Object



174
175
176
177
178
179
180
181
# File 'lib/carray/iterator.rb', line 174

def put (*idx)
  val = idx.pop
  elements.times do |addr|
    blk = kernel_at_addr(addr)
    blk[*idx] = val
  end
  return self
end

#rankObject

yard:

class CAIterator
  def ndim
  end
end


218
219
220
221
222
# File 'ext/carray_iterator.c', line 218

VALUE
rb_ca_iter_ndim (VALUE self)
{
  return LONG2NUM(ca_iter_ndim(self));
}

#referenceObject

yard:

class CAIterator
  def reference
  end
end


266
267
268
269
270
# File 'ext/carray_iterator.c', line 266

VALUE
rb_ca_iter_reference (VALUE self)
{
  return ca_iter_reference(self);
}

#shapeObject

yard:

class CAIterator
  def dim
  end
end


231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'ext/carray_iterator.c', line 231

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

#sort_by(&block) ⇒ Object



273
274
275
276
277
278
279
280
# File 'lib/carray/iterator.rb', line 273

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) ⇒ Object



267
268
269
270
271
# File 'lib/carray/iterator.rb', line 267

def sort_by! (&block)
  ia = self.ca
  ia[] = ia.to_a.sort_by(&block).map{|x| x.to_ca }
  return reference
end

#sort_with(&block) ⇒ Object



282
283
284
285
286
287
288
289
290
# File 'lib/carray/iterator.rb', line 282

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_aObject



123
124
125
# File 'lib/carray/iterator.rb', line 123

def to_a
  return ca.to_a
end