mpipe 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 638f1385e64bf50aedff83fbdec7cf8de6f2e63b
4
+ data.tar.gz: e16b54cc652d0f6503cd4776bf716903fcaf2703
5
+ SHA512:
6
+ metadata.gz: df234ecdd079cb9b24f7afb9c8c1f8ce585cd247f6286a4c49e8484b5b7296ec2445ffb3cf603d5a2ef69be8dd567b6c8a03905f6c0d3a96b793869c76e2839f
7
+ data.tar.gz: 5872d1e9ab4b7536d50d55a9cb778a9d43cc140b81e6bdaed70388b19af051956039e03554338ee11399a8f56af39c40c10a9130f0e2bdca67deb0acc9172d7a
@@ -0,0 +1,49 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ tmp/
12
+
13
+ ## Specific to RubyMotion:
14
+ .dat*
15
+ .repl_history
16
+ build/
17
+
18
+ ## Documentation cache and generated files:
19
+ .yardoc/
20
+ _yardoc/
21
+ doc/
22
+ rdoc/
23
+
24
+ ## Environment normalization:
25
+ /.bundle/
26
+ /vendor/bundle
27
+ /lib/bundler/man/
28
+
29
+ # for a library or gem, you might want to ignore these files since the code is
30
+ # intended to run in multiple environments; otherwise, check them in:
31
+ Gemfile.lock
32
+ .ruby-version
33
+ .ruby-gemset
34
+
35
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
36
+ .rvmrc
37
+
38
+ # setup.rb
39
+ /SetupConfig
40
+ /SetupReceipt
41
+
42
+ # Build files for extension
43
+ *~
44
+ *.o
45
+ *.so
46
+ TAGS
47
+ t.rb
48
+ *.bak[0-9]
49
+ bak
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mpipe.gemspec
4
+ gemspec
@@ -0,0 +1,76 @@
1
+ # MPipe
2
+
3
+ Ruby's IO.pipe emulation over MPI
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'mpipe'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install mpipe
20
+
21
+ ## Usage
22
+
23
+ test code: t.rb
24
+ ```ruby
25
+ require "mpipe"
26
+
27
+ MPipe.init
28
+ rank = MPipe::Comm.rank
29
+ size = MPipe::Comm.size
30
+ puts "size=%d rank=%d pid=%d" % [size,rank,Process.pid]
31
+
32
+ if rank == 0
33
+
34
+ (1..size-1).each do |r|
35
+ p MPipe.new(r).read
36
+ end
37
+
38
+ else
39
+
40
+ sleep rank
41
+ MPipe.new(0).write("Hello from #{rank}")
42
+
43
+ end
44
+ ```
45
+
46
+ execute:
47
+ ```
48
+ $ mpirun -np 4 ruby t.rb
49
+ size=4 rank=0 pid=10353
50
+ "Hello from 1"
51
+ size=4 rank=1 pid=10354
52
+ "Hello from 2"
53
+ size=4 rank=2 pid=10355
54
+ "Hello from 3"
55
+ size=4 rank=3 pid=10356
56
+ ```
57
+
58
+ ## API
59
+
60
+ ```
61
+ MPipe.init(*args) -- calls MPI_Init()
62
+ MPipe.finalize -- calls MPI_Finalize()
63
+ MPipe.abort(errorcode) -- calls MPI_Abort(MPI_COMM_WORLD, errorcode)
64
+ MPipe::Comm.rank -- calls MPI_Comm_rank(), return the rank of this process.
65
+ MPipe::Comm.size -- calls MPI_Comm_size(), return the size of this environment.
66
+
67
+ mp = MPipe.new(rank) -- returns pipe to MPI process with rank.
68
+ mp.write(str) -- emulate IO#write.
69
+ mp.read(maxlen,outbuf) -- emulate IO#read.
70
+ mp.read_nonblock(maxlen,outbuf) -- emulate IO#read_nonblock.
71
+ MPipe.select(array_of_mpipe) -- emulate IO.select
72
+ ```
73
+
74
+ ## Contributing
75
+
76
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Masahiro TANAKA/mpipe.
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,9 @@
1
+ require "mkmf"
2
+
3
+ dir_config("mpi")
4
+
5
+ CONFIG['CC'] = "mpicc"
6
+
7
+ $objs = %w(mpipe.o)
8
+
9
+ create_makefile("mpipe")
@@ -0,0 +1,584 @@
1
+ #include "ruby.h"
2
+ #include "ruby/io.h"
3
+ //#include "ruby/encoding.h"
4
+ #include "mpi.h"
5
+
6
+ #define MPIPE_VERSION "0.1.0"
7
+
8
+ static int mp_buffer_size = 4098;
9
+ static int mp_initialized = 0;
10
+ static int mp_finalized = 0;
11
+ static VALUE sym_exception;
12
+ static VALUE eEAGAINWaitReadable;
13
+ static ID id_allocated_mpipe;
14
+
15
+ struct MPipe {
16
+ int rank;
17
+ char *send_buffer;
18
+ char *recv_buffer;
19
+ MPI_Request send_request;
20
+ MPI_Request recv_request;
21
+ int send_count;
22
+ int recv_count;
23
+ int recv_begin;
24
+ };
25
+
26
+ #define IS_MPIPE(obj) (rb_typeddata_is_kind_of((obj), &mp_data_type))
27
+ #define error_inval(msg) (rb_syserr_fail(EINVAL, msg))
28
+ //#define get_enc(ptr) ((ptr)->enc ? (ptr)->enc : rb_enc_get((ptr)->string))
29
+ #define get_enc(ptr) ((ptr)->enc)
30
+
31
+ static void
32
+ mp_finalize()
33
+ {
34
+ if (mp_initialized && !mp_finalized) {
35
+ mp_finalized = 1;
36
+ MPI_Finalize();
37
+ }
38
+ }
39
+
40
+ static VALUE
41
+ mp_mpi_init(int argc, VALUE *argv, VALUE klass)
42
+ {
43
+ char **cargv;
44
+ VALUE progname, mpipe_ary;
45
+ int i, size;
46
+
47
+ cargv = ALLOCA_N(char *, argc+1);
48
+ progname = rb_gv_get("$0");
49
+ cargv[0] = StringValueCStr(progname);
50
+
51
+ for(i=0; i<argc; i++) {
52
+ if (TYPE(argv[i]) == T_STRING) {
53
+ cargv[i+1] = StringValueCStr(argv[i]);
54
+ } else {
55
+ rb_raise(rb_eArgError, "argument must be string");
56
+ }
57
+ }
58
+ argc++;
59
+
60
+ MPI_Init(&argc, &cargv);
61
+
62
+ if (mp_initialized) {
63
+ return Qnil;
64
+ } else {
65
+ mp_initialized = 1;
66
+ }
67
+ atexit(mp_finalize);
68
+
69
+ MPI_Comm_size(MPI_COMM_WORLD, &size);
70
+ mpipe_ary = rb_ary_new2(size);
71
+ rb_ivar_set(klass, id_allocated_mpipe, mpipe_ary);
72
+
73
+ return Qnil;
74
+ }
75
+
76
+ static VALUE
77
+ mp_mpi_finalize(VALUE klass)
78
+ {
79
+ mp_finalize();
80
+ return Qnil;
81
+ }
82
+
83
+ static VALUE
84
+ mp_mpi_abort(VALUE klass, VALUE rerror)
85
+ {
86
+ int ierror;
87
+
88
+ ierror = MPI_Abort(MPI_COMM_WORLD, NUM2INT(rerror));
89
+ return INT2NUM(ierror);
90
+ }
91
+
92
+ static VALUE
93
+ mp_mpi_buffer_size(VALUE mod)
94
+ {
95
+ return INT2NUM(mp_buffer_size);
96
+ }
97
+
98
+ static VALUE
99
+ mp_mpi_set_buffer_size(VALUE mod, VALUE size)
100
+ {
101
+ if (mp_initialized) {
102
+ rb_raise(rb_eStandardError,"buffer_size must be set before MPipe.init");
103
+ }
104
+ mp_buffer_size = NUM2INT(size);
105
+ return size;
106
+ }
107
+
108
+ static VALUE
109
+ mp_comm_size(VALUE self)
110
+ {
111
+ int size;
112
+
113
+ MPI_Comm_size(MPI_COMM_WORLD, &size);
114
+ return INT2NUM(size);
115
+ }
116
+
117
+ static VALUE
118
+ mp_comm_rank(VALUE self)
119
+ {
120
+ int rank;
121
+
122
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
123
+ return INT2NUM(rank);
124
+ }
125
+
126
+ // ---------------------------------------------------------
127
+
128
+ static struct MPipe *
129
+ mp_alloc(void)
130
+ {
131
+ struct MPipe *ptr = ALLOC(struct MPipe);
132
+ ptr->rank = -1;
133
+ ptr->send_buffer = 0;
134
+ ptr->recv_buffer = 0;
135
+ ptr->send_count = 0;
136
+ ptr->recv_count = 0;
137
+ ptr->recv_begin = 0;
138
+ return ptr;
139
+ }
140
+
141
+ static void
142
+ mp_free(void *p)
143
+ {
144
+ struct MPipe *ptr = p;
145
+
146
+ //if (--ptr->count <= 0) {
147
+ if (ptr) {
148
+
149
+ if (ptr->send_count == -1) {
150
+ MPI_Request_free(&ptr->send_request);
151
+ ptr->send_count = 0;
152
+ }
153
+ if (ptr->recv_count == -1) {
154
+ MPI_Request_free(&ptr->recv_request);
155
+ ptr->recv_count = 0;
156
+ }
157
+ if (ptr->send_buffer) {
158
+ xfree(ptr->send_buffer);
159
+ ptr->send_buffer = 0;
160
+ }
161
+ if (ptr->recv_buffer) {
162
+ xfree(ptr->recv_buffer);
163
+ ptr->recv_buffer = 0;
164
+ }
165
+
166
+ xfree(ptr);
167
+ }
168
+ }
169
+
170
+ static size_t
171
+ mp_memsize(const void *p)
172
+ {
173
+ return sizeof(struct MPipe) + mp_buffer_size*2;
174
+ }
175
+
176
+ static const rb_data_type_t mp_data_type = {
177
+ "mpipe",
178
+ {
179
+ 0,
180
+ mp_free,
181
+ mp_memsize,
182
+ },
183
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
184
+ };
185
+
186
+ #define check_mpipe(self) ((struct MPipe*)rb_check_typeddata((self), &mp_data_type))
187
+
188
+ static struct MPipe*
189
+ get_mpipe(VALUE self)
190
+ {
191
+ struct MPipe *ptr = check_mpipe(rb_io_taint_check(self));
192
+
193
+ if (!ptr) {
194
+ rb_raise(rb_eIOError, "uninitialized stream");
195
+ }
196
+ return ptr;
197
+ }
198
+
199
+ #define MPipe(obj) get_mpipe(obj)
200
+
201
+ static VALUE
202
+ mp_s_allocate(VALUE klass)
203
+ {
204
+ return TypedData_Wrap_Struct(klass, &mp_data_type, 0);
205
+ }
206
+
207
+ static VALUE
208
+ mp_init(struct MPipe *ptr, VALUE self, VALUE rank)
209
+ {
210
+ ptr->rank = NUM2INT(rank);
211
+ ptr->send_buffer = malloc(mp_buffer_size);
212
+ ptr->recv_buffer = malloc(mp_buffer_size);
213
+ return self;
214
+ }
215
+
216
+ /*
217
+ * call-seq: MPipe.new(string=""[, mode])
218
+ *
219
+ * Creates new MPipe instance from with _string_ and _mode_.
220
+ */
221
+ static VALUE
222
+ mp_initialize(VALUE self, VALUE rank)
223
+ {
224
+ struct MPipe *ptr = check_mpipe(self);
225
+
226
+ if (!ptr) {
227
+ DATA_PTR(self) = ptr = mp_alloc();
228
+ }
229
+ rb_call_super(0, 0);
230
+ return mp_init(ptr, self, rank);
231
+ }
232
+
233
+ /* :nodoc: */
234
+ static VALUE
235
+ mp_s_new(VALUE klass, VALUE vrank)
236
+ {
237
+ VALUE mpipe, mpipe_ary;
238
+ int rank;
239
+
240
+ rank = NUM2INT(vrank);
241
+ mpipe_ary = rb_ivar_get(klass, id_allocated_mpipe);
242
+ mpipe = rb_ary_entry(mpipe_ary, rank);
243
+ if (NIL_P(mpipe)) {
244
+ mpipe = rb_class_new_instance(1, &vrank, klass);
245
+ rb_ary_store(mpipe_ary, rank, mpipe);
246
+ }
247
+ return mpipe;
248
+ }
249
+
250
+
251
+ #if 0
252
+ /*
253
+ * Returns +false+. Just for compatibility to IO.
254
+ */
255
+ static VALUE
256
+ mp_false(VALUE self)
257
+ {
258
+ MPipe(self);
259
+ return Qfalse;
260
+ }
261
+ #endif
262
+
263
+ /*
264
+ * Returns +nil+. Just for compatibility to IO.
265
+ */
266
+ static VALUE
267
+ mp_nil(VALUE self)
268
+ {
269
+ MPipe(self);
270
+ return Qnil;
271
+ }
272
+
273
+ #if 0
274
+ /*
275
+ * Returns *pipempi* itself. Just for compatibility to IO.
276
+ */
277
+ static VALUE
278
+ mp_self(VALUE self)
279
+ {
280
+ MPipe(self);
281
+ return self;
282
+ }
283
+
284
+ /*
285
+ * Returns 0. Just for compatibility to IO.
286
+ */
287
+ static VALUE
288
+ mp_0(VALUE self)
289
+ {
290
+ MPipe(self);
291
+ return INT2FIX(0);
292
+ }
293
+
294
+ /*
295
+ * Returns the argument unchanged. Just for compatibility to IO.
296
+ */
297
+ static VALUE
298
+ mp_first(VALUE self, VALUE arg)
299
+ {
300
+ MPipe(self);
301
+ return arg;
302
+ }
303
+
304
+ /*
305
+ * Raises NotImplementedError.
306
+ */
307
+ static VALUE
308
+ mp_unimpl(int argc, VALUE *argv, VALUE self)
309
+ {
310
+ MPipe(self);
311
+ rb_notimplement();
312
+
313
+ UNREACHABLE;
314
+ }
315
+ #endif
316
+
317
+ #define mp_close mp_nil
318
+
319
+ static VALUE
320
+ mp_write(VALUE self, VALUE str)
321
+ {
322
+ struct MPipe *ptr = MPipe(self);
323
+ int istat;
324
+ int pos, count;
325
+
326
+ str = StringValue(str);
327
+ pos = 0;
328
+
329
+ while (pos < RSTRING_LEN(str)) {
330
+ count = RSTRING_LEN(str) - pos;
331
+ if (count > mp_buffer_size) {
332
+ count = mp_buffer_size;
333
+ }
334
+ memcpy(ptr->send_buffer, RSTRING_PTR(str)+pos, count);
335
+
336
+ istat = MPI_Send(ptr->send_buffer, count, MPI_CHAR, ptr->rank,
337
+ 0, MPI_COMM_WORLD);
338
+ if (istat != MPI_SUCCESS) {
339
+ rb_raise(rb_eStandardError,"MPI_send failed with status=%d\n",istat);
340
+ }
341
+
342
+ pos += count;
343
+ }
344
+ return self;
345
+ }
346
+
347
+
348
+
349
+ static VALUE
350
+ mp_outbuf(char *buf, int len, VALUE outbuf)
351
+ {
352
+ if (NIL_P(outbuf)) {
353
+ return rb_str_new(buf, len);
354
+ } else {
355
+ rb_str_resize(outbuf, len);
356
+ MEMCPY(RSTRING_PTR(outbuf), buf, char, len);
357
+ return outbuf;
358
+ }
359
+ }
360
+
361
+ static VALUE
362
+ mp_substr(struct MPipe *ptr, VALUE maxlen, VALUE outbuf)
363
+ {
364
+ int max_len;
365
+ int count = ptr->recv_count;
366
+ char *recv_buf = ptr->recv_buffer + ptr->recv_begin;
367
+
368
+ if (!NIL_P(maxlen)) {
369
+ max_len = NUM2INT(maxlen);
370
+ if (max_len < 0) {
371
+ rb_raise(rb_eArgError, "negative length %d given", max_len);
372
+ }
373
+ if (max_len < count) {
374
+ ptr->recv_begin += max_len;
375
+ ptr->recv_count -= max_len;
376
+ return mp_outbuf(recv_buf, max_len, outbuf);
377
+ }
378
+ }
379
+ ptr->recv_begin = 0;
380
+ ptr->recv_count = 0;
381
+ return mp_outbuf(recv_buf, count, outbuf);
382
+ }
383
+
384
+
385
+ static VALUE
386
+ mp_read(int argc, VALUE *argv, VALUE self)
387
+ {
388
+ struct MPipe *ptr = MPipe(self);
389
+ MPI_Status status;
390
+ int istat;
391
+ int count;
392
+ VALUE maxlen = Qnil;
393
+ VALUE outbuf = Qnil;
394
+
395
+ rb_scan_args(argc, argv, "02", &maxlen, &outbuf);
396
+
397
+ if (ptr->recv_count > 0) {
398
+ return mp_substr(ptr, maxlen, outbuf);
399
+ }
400
+ if (ptr->recv_count == 0) {
401
+ istat = MPI_Recv(ptr->recv_buffer, mp_buffer_size, MPI_CHAR, ptr->rank,
402
+ 0, MPI_COMM_WORLD, &status);
403
+ if (istat != MPI_SUCCESS) {
404
+ rb_raise(rb_eStandardError,"MPI_recv failed with status=%d\n",istat);
405
+ }
406
+ } else { // requesting
407
+ istat = MPI_Wait(&ptr->recv_request, &status);
408
+ if (istat != MPI_SUCCESS) {
409
+ rb_raise(rb_eStandardError,"MPI_Wait failed with status=%d",istat);
410
+ }
411
+ }
412
+ MPI_Get_count(&status, MPI_CHAR, &count);
413
+ ptr->recv_count = count;
414
+ return mp_substr(ptr, maxlen, outbuf);
415
+ }
416
+
417
+
418
+
419
+ static void
420
+ request_irecv(struct MPipe *ptr)
421
+ {
422
+ int istat;
423
+
424
+ if (ptr->recv_count == 0) {
425
+ istat = MPI_Irecv(ptr->recv_buffer, mp_buffer_size, MPI_CHAR, ptr->rank,
426
+ 0, MPI_COMM_WORLD, &ptr->recv_request);
427
+ if (istat != MPI_SUCCESS) {
428
+ rb_raise(rb_eStandardError,"MPI_Irecv failed with status=%d",istat);
429
+ }
430
+ ptr->recv_count = -1; // requesting
431
+ }
432
+ }
433
+
434
+ /*
435
+ not requesting: recv_count=0
436
+ requesting: recv_count=-1
437
+ buffered: recv_count=n
438
+ */
439
+
440
+ /*
441
+ * call-seq:
442
+ * mpipe.read_nonblock(integer[, outbuf [, opts]]) -> string
443
+ *
444
+ * Similar to #read, but raises +EOFError+ at end of string unless the
445
+ * +exception: false+ option is passed in.
446
+ */
447
+ static VALUE
448
+ mp_read_nonblock(int argc, VALUE *argv, VALUE self)
449
+ {
450
+ struct MPipe *ptr = MPipe(self);
451
+ MPI_Status status;
452
+ int istat;
453
+ int count;
454
+ int complete = 0;
455
+ VALUE maxlen = Qnil;
456
+ VALUE outbuf = Qnil;
457
+ VALUE opts = Qnil;
458
+ VALUE val;
459
+
460
+ rb_scan_args(argc, argv, "02:", &maxlen, &outbuf, &opts);
461
+
462
+ if (ptr->recv_count > 0) {
463
+ return mp_substr(ptr, maxlen, outbuf);
464
+ }
465
+ request_irecv(ptr);
466
+ istat = MPI_Test(&ptr->recv_request, &complete, &status);
467
+ if (istat != MPI_SUCCESS) {
468
+ rb_raise(rb_eStandardError,"MPI_Test failed with status=%d",istat);
469
+ }
470
+ if (complete) {
471
+ MPI_Get_count(&status, MPI_CHAR, &count);
472
+ ptr->recv_count = count;
473
+ val = mp_substr(ptr, maxlen, outbuf);
474
+ } else {
475
+ if (!NIL_P(opts) &&
476
+ rb_hash_lookup2(opts, sym_exception, Qundef) == Qfalse) {
477
+ return Qnil;
478
+ } else {
479
+ rb_raise(eEAGAINWaitReadable,"MPI_Irecv would block");
480
+ }
481
+ }
482
+ return val;
483
+ }
484
+
485
+ static VALUE
486
+ mp_s_select(int argc, VALUE *argv, VALUE mod)
487
+ {
488
+ struct MPipe *ptr;
489
+ MPI_Request *ary_of_requests;
490
+ int *ary_of_indices;
491
+ MPI_Status *ary_of_statuses;
492
+ int incount, outcount;
493
+ int i, count, istat;
494
+ VALUE rd_ary, result_ary, item;
495
+
496
+ if (argc==0) {
497
+ rb_raise(rb_eArgError, "no argument");
498
+ }
499
+ incount = RARRAY_LEN(argv[0]);
500
+
501
+ result_ary = rb_ary_new();
502
+ rd_ary = rb_ary_new();
503
+ rb_ary_push(result_ary, rd_ary);
504
+ for (i=0; i < incount; i++) {
505
+ item = RARRAY_AREF(argv[0], i);
506
+ ptr = MPipe(item);
507
+ if (ptr->recv_count > 0) {
508
+ rb_ary_push(rd_ary, item);
509
+ }
510
+ }
511
+ if (RARRAY_LEN(rd_ary) > 0) {
512
+ return result_ary;
513
+ }
514
+
515
+ ary_of_requests = ALLOCA_N(MPI_Request, incount);
516
+ ary_of_statuses = ALLOCA_N(MPI_Status, incount);
517
+ ary_of_indices = ALLOCA_N(int, incount);
518
+
519
+ for (i=0; i < incount; i++) {
520
+ item = RARRAY_AREF(argv[0], i);
521
+ ptr = MPipe(item);
522
+ request_irecv(ptr);
523
+ ary_of_requests[i] = ptr->recv_request;
524
+ }
525
+
526
+ istat = MPI_Waitsome(incount, ary_of_requests,
527
+ &outcount, ary_of_indices, ary_of_statuses);
528
+ if (istat != MPI_SUCCESS) {
529
+ rb_raise(rb_eStandardError,"MPI_Waitany failed with status=%d",istat);
530
+ }
531
+
532
+ for (i=0; i < outcount; i++) {
533
+ item = RARRAY_AREF(argv[0], ary_of_indices[i]);
534
+ MPI_Get_count(&ary_of_statuses[i], MPI_BYTE, &count);
535
+ ptr = MPipe(item);
536
+ ptr->recv_count = count;
537
+ rb_ary_push(rd_ary, item);
538
+ }
539
+ return result_ary;
540
+ }
541
+
542
+
543
+ void Init_mpipe()
544
+ {
545
+ VALUE cMPipe, mComm;
546
+
547
+ cMPipe = rb_define_class("MPipe", rb_cData);
548
+
549
+ // MPI
550
+ rb_define_module_function(cMPipe, "init", mp_mpi_init, -1);
551
+ rb_define_module_function(cMPipe, "finalize", mp_mpi_finalize, 0);
552
+ rb_define_module_function(cMPipe, "abort", mp_mpi_abort, 1);
553
+ rb_define_module_function(cMPipe, "buffer_size", mp_mpi_buffer_size, 0);
554
+ rb_define_module_function(cMPipe, "buffer_size=", mp_mpi_set_buffer_size, 1);
555
+
556
+ rb_define_const(cMPipe, "VERSION", rb_str_new2(MPIPE_VERSION));
557
+ rb_define_const(cMPipe, "MPI_VERSION", INT2NUM(MPI_VERSION));
558
+ rb_define_const(cMPipe, "MPI_SUBVERSION", INT2NUM(MPI_SUBVERSION));
559
+ rb_define_const(cMPipe, "SUCCESS", INT2NUM(MPI_SUCCESS));
560
+ rb_define_const(cMPipe, "PROC_NULL", INT2NUM(MPI_PROC_NULL));
561
+
562
+ // MPI::Comm
563
+ mComm = rb_define_module_under(cMPipe, "Comm");
564
+ rb_define_module_function(mComm, "rank", mp_comm_rank, 0);
565
+ rb_define_module_function(mComm, "size", mp_comm_size, 0);
566
+
567
+ //rb_include_module(cMPipe, rb_mEnumerable);
568
+ rb_define_alloc_func(cMPipe, mp_s_allocate);
569
+ rb_define_singleton_method(cMPipe, "new", mp_s_new, 1);
570
+ rb_define_method(cMPipe, "initialize", mp_initialize, 1);
571
+
572
+ rb_define_method(cMPipe, "write", mp_write, 1);
573
+ rb_define_method(cMPipe, "write_nonblock", mp_write, 1);
574
+ rb_define_method(cMPipe, "print", mp_write, 1);
575
+ rb_define_method(cMPipe, "read", mp_read, -1);
576
+ rb_define_method(cMPipe, "read_nonblock", mp_read_nonblock, -1);
577
+ rb_define_method(cMPipe, "close", mp_close, 1);
578
+
579
+ rb_define_singleton_method(cMPipe, "select", mp_s_select, -1);
580
+
581
+ sym_exception = ID2SYM(rb_intern("exception"));
582
+ id_allocated_mpipe = rb_intern("allocated_mpipe");
583
+ eEAGAINWaitReadable = rb_const_get(rb_cIO, rb_intern("EWOULDBLOCKWaitReadable"));
584
+ }