ruby-mpi 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 20fe1ffeb2cd83c63f27589552a8578a5890de22
4
+ data.tar.gz: fa319f8be8c7ce5b9287a1c58f9fd848f1f364fe
5
+ SHA512:
6
+ metadata.gz: bff7b2110e2c36af4507a8664cce6251ed2f8e890a9d56afbc960ff83b8904ac76273885e0ed5a327fb13593bdfa119b0b9232c8b3157f3523ffea3f2c73885e
7
+ data.tar.gz: c42acd7ec6937987e394610ce94bf1e31ba648e0c544710767e7472ae86d3fcd2ff2d7507928052fa46d208b4450540ec1d65c3913f27ed3f57d3de0a85d6fca
data/Gemfile CHANGED
@@ -6,9 +6,9 @@ source "http://rubygems.org"
6
6
  # Add dependencies to develop your gem here.
7
7
  # Include everything needed to run rake, tests, features, etc.
8
8
  group :development do
9
- gem "rspec", "~> 2.3.0"
10
- gem "bundler", "~> 1.0.0"
11
- gem "jeweler", "~> 1.5.2"
12
- gem "rcov", ">= 0"
9
+ gem "rspec", ">= 2.3.0"
10
+ gem "bundler", ">= 1.0.0"
11
+ gem "jeweler", ">= 1.5.2"
12
+ gem "simplecov", ">= 0"
13
13
  gem "narray", ">= 0"
14
14
  end
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011 Seiya Nishizawa
1
+ Copyright (c) 2011-2012 Seiya Nishizawa
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -5,6 +5,11 @@ Ruby-MPI is a ruby binding of Message Passing Interface (MPI), which is an API s
5
5
  == Install
6
6
 
7
7
  # gem install ruby-mpi
8
+
9
+ == How to run
10
+ Use mpirun or mpiexec to run a script
11
+ e.g. (run with 4 processes)
12
+ # mpirun -np 4 ruby hello.rb
8
13
 
9
14
  == Contributing to Ruby-MPI
10
15
 
@@ -18,6 +23,6 @@ Ruby-MPI is a ruby binding of Message Passing Interface (MPI), which is an API s
18
23
 
19
24
  == Copyright
20
25
 
21
- Copyright (c) 2011 Seiya Nishizawa. See LICENSE.txt for
26
+ Copyright (c) 2011-2012 Seiya Nishizawa. See LICENSE.txt for
22
27
  further details.
23
28
 
data/Rakefile CHANGED
@@ -40,7 +40,7 @@ end
40
40
 
41
41
  task :default => :spec
42
42
 
43
- require 'rake/rdoctask'
43
+ require 'rdoc/task'
44
44
  Rake::RDocTask.new do |rdoc|
45
45
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
46
46
 
@@ -48,6 +48,7 @@ Rake::RDocTask.new do |rdoc|
48
48
  rdoc.title = "ruby-mpi #{version}"
49
49
  rdoc.rdoc_files.include('README*')
50
50
  rdoc.rdoc_files.include('lib/**/*.rb')
51
+ rdoc.rdoc_files.include('samples/*.rb')
51
52
  end
52
53
 
53
54
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
data/ext/mpi/extconf.rb CHANGED
@@ -4,12 +4,20 @@ CONFIG['CC'] = "mpicc"
4
4
  gem_path = nil
5
5
  begin
6
6
  require "rubygems"
7
- if (spec = Gem.source_index.find_name("narray")).any?
8
- gem_path = spec.last.full_gem_path
7
+ if Gem::Specification.respond_to?(:find_by_name)
8
+ if spec = Gem::Specification.find_by_name("narray")
9
+ gem_path = spec.full_gem_path
10
+ end
11
+ else
12
+ if (spec = Gem.source_index.find_name("narray")).any?
13
+ gem_path = spec.full_gem_path
14
+ end
9
15
  end
10
16
  rescue LoadError
11
17
  dir_config("narray", Config::CONFIG["sitearchdir"])
12
18
  end
13
- find_header("narray.h", gem_path)
19
+ unless find_header("narray.h", gem_path)
20
+ find_header("narray.h", File.join(gem_path,"src"))
21
+ end
14
22
 
15
23
  create_makefile("mpi")
data/ext/mpi/mpi.c CHANGED
@@ -6,38 +6,45 @@
6
6
  #include "mpi.h"
7
7
 
8
8
 
9
- #define OBJ2C(rb_obj, len, buffer, typ) \
9
+ #define OBJ2C(rb_obj, len, buffer, typ, off) \
10
10
  {\
11
11
  if (TYPE(rb_obj) == T_STRING) {\
12
- len = RSTRING_LEN(rb_obj);\
13
- buffer = (void*)StringValuePtr(rb_obj);\
14
- typ = MPI_CHAR;\
15
- } else if (IsNArray(rb_obj)) { \
12
+ if (len==0) len = RSTRING_LEN(rb_obj);\
13
+ buffer = (void*)(StringValuePtr(rb_obj) + off);\
14
+ typ = MPI_BYTE;\
15
+ } else if (IsNArray(rb_obj)) {\
16
16
  struct NARRAY *a;\
17
17
  GetNArray(rb_obj, a);\
18
18
  buffer = (void*)(a->ptr);\
19
- len = a->total;\
19
+ if (len==0) len = a->total;\
20
20
  switch (a->type) {\
21
21
  case NA_BYTE:\
22
22
  typ = MPI_BYTE;\
23
+ buffer = (void*)((char*)buffer + off);\
23
24
  break;\
24
25
  case NA_SINT:\
25
26
  typ = MPI_SHORT;\
27
+ buffer = (void*)((char*)buffer + off*4);\
26
28
  break;\
27
29
  case NA_LINT:\
28
30
  typ = MPI_LONG;\
31
+ buffer = (void*)((char*)buffer + off*8);\
29
32
  break;\
30
33
  case NA_SFLOAT:\
31
34
  typ = MPI_FLOAT;\
35
+ buffer = (void*)((char*)buffer + off*4);\
32
36
  break;\
33
37
  case NA_DFLOAT:\
34
38
  typ = MPI_DOUBLE;\
39
+ buffer = (void*)((char*)buffer + off*8);\
35
40
  break;\
36
41
  case NA_SCOMPLEX:\
37
42
  typ = MPI_2COMPLEX;\
43
+ buffer = (void*)((char*)buffer + off*8);\
38
44
  break;\
39
45
  case NA_DCOMPLEX:\
40
46
  typ = MPI_2DOUBLE_COMPLEX;\
47
+ buffer = (void*)((char*)buffer + off*16);\
41
48
  break;\
42
49
  default:\
43
50
  rb_raise(rb_eArgError, "narray type is invalid");\
@@ -54,48 +61,36 @@ static VALUE eBUFFER, eCOUNT, eTYPE, eTAG, eCOMM, eRANK, eREQUEST, eROOT, eGROUP
54
61
 
55
62
  struct _Comm {
56
63
  MPI_Comm Comm;
64
+ bool free;
57
65
  };
58
66
  struct _Request {
59
67
  MPI_Request Request;
68
+ bool free;
60
69
  };
61
70
  struct _Op {
62
71
  MPI_Op Op;
72
+ bool free;
63
73
  };
64
74
  struct _Errhandler {
65
75
  MPI_Errhandler Errhandler;
76
+ bool free;
66
77
  };
67
78
 
68
79
  static bool _initialized = false;
69
80
  static bool _finalized = false;
70
81
 
71
82
 
72
- #define DEF_FREE(name) \
73
- static void \
74
- name ## _free(void *ptr)\
75
- {\
76
- struct _ ## name *obj;\
77
- obj = (struct _ ## name*) ptr;\
78
- if (!_finalized)\
79
- MPI_ ## name ## _free(&(obj->name)); \
80
- free(obj);\
81
- }
82
- DEF_FREE(Comm)
83
- DEF_FREE(Request)
84
- DEF_FREE(Op)
85
- DEF_FREE(Errhandler)
86
- static void
87
- Status_free(void *ptr)
88
- {
89
- free((MPI_Status*) ptr);
90
- }
91
-
92
-
93
- #define CAE_ERR(type) case MPI_ERR_ ## type: rb_raise(e ## type,""); break
83
+ #define CAE_ERR(type) case MPI_ERR_ ## type: rb_raise(e ## type,"%s",str); break
94
84
  static void
95
85
  check_error(int error)
96
86
  {
97
- switch (error) {
98
- case MPI_SUCCESS: break;
87
+ if (error == MPI_SUCCESS) return;
88
+ int code, len;
89
+ char str[MPI_MAX_ERROR_STRING];
90
+ if (MPI_Error_class(error, &code)!=MPI_SUCCESS || MPI_Error_string(error, str, &len)!=MPI_SUCCESS)
91
+ rb_raise(rb_eRuntimeError, "unknown error occuerd in MPI call");
92
+
93
+ switch (code) {
99
94
  CAE_ERR(BUFFER);
100
95
  CAE_ERR(COUNT);
101
96
  CAE_ERR(TYPE);
@@ -154,15 +149,48 @@ check_error(int error)
154
149
  CAE_ERR(SYSRESOURCE);
155
150
  #endif
156
151
  default:
157
- rb_raise(rb_eRuntimeError, "unknown error");
152
+ rb_raise(rb_eRuntimeError, "unknown error: %d", code);
158
153
  }
159
154
  }
160
155
 
156
+ #define DEF_FREE(name, capit) \
157
+ static void \
158
+ name ## _free(void *ptr)\
159
+ {\
160
+ struct _ ## name *obj;\
161
+ obj = (struct _ ## name*) ptr;\
162
+ if (!_finalized && obj->free && obj->name!=MPI_ ## capit ##_NULL)\
163
+ check_error(MPI_ ## name ## _free(&(obj->name))); \
164
+ free(obj);\
165
+ }
166
+ #define DEF_FREE2(name, capit) \
167
+ static void \
168
+ name ## _free2(void *ptr)\
169
+ {\
170
+ struct _ ## name *obj;\
171
+ obj = (struct _ ## name*) ptr;\
172
+ free(obj);\
173
+ }
174
+ DEF_FREE(Comm, COMM)
175
+ DEF_FREE(Request, REQUEST)
176
+ DEF_FREE(Op, OP)
177
+ DEF_FREE(Errhandler, ERRHANDLER)
178
+ DEF_FREE2(Comm, COMM)
179
+ DEF_FREE2(Op, OP)
180
+ DEF_FREE2(Errhandler, ERRHANDLER)
181
+ static void
182
+ Status_free(void *ptr)
183
+ {
184
+ free((MPI_Status*) ptr);
185
+ }
186
+
187
+
161
188
  #define DEF_CONST(v, const, name) \
162
189
  {\
163
190
  v = ALLOC(struct _ ## v);\
164
191
  v->v = const;\
165
- rb_define_const(c ## v, #name, Data_Wrap_Struct(c ## v, NULL, v ## _free, v)); \
192
+ v->free = false;\
193
+ rb_define_const(c ## v, #name, Data_Wrap_Struct(c ## v, NULL, v ## _free2, v)); \
166
194
  }
167
195
 
168
196
  static void
@@ -216,7 +244,7 @@ rb_m_init(int argc, VALUE *argv, VALUE self)
216
244
  // define MPI::Comm::WORLD
217
245
  struct _Comm *Comm;
218
246
  DEF_CONST(Comm, MPI_COMM_WORLD, WORLD);
219
- MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
247
+ check_error(MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN));
220
248
 
221
249
  // define MPI::Op::???
222
250
  struct _Op *Op;
@@ -249,6 +277,16 @@ rb_m_finalize(VALUE self)
249
277
  return self;
250
278
  }
251
279
 
280
+ static VALUE
281
+ rb_m_abort(VALUE self, VALUE rcomm, VALUE rerror)
282
+ {
283
+ struct _Comm *comm;
284
+ int ierror;
285
+ Data_Get_Struct(rcomm, struct _Comm, comm);
286
+ ierror = MPI_Abort(comm->Comm, NUM2INT(rerror));
287
+ return INT2NUM(ierror);
288
+ }
289
+
252
290
 
253
291
  // MPI::Comm
254
292
  static VALUE
@@ -262,6 +300,7 @@ rb_comm_initialize(VALUE self)
262
300
  {
263
301
  rb_raise(rb_eRuntimeError, "not developed yet");
264
302
  // MPI_Comm_create()
303
+ // comm->free = true;
265
304
  }
266
305
  static VALUE
267
306
  rb_comm_size(VALUE self)
@@ -285,11 +324,11 @@ static VALUE
285
324
  rb_comm_send(VALUE self, VALUE rb_obj, VALUE rb_dest, VALUE rb_tag)
286
325
  {
287
326
  void* buffer;
288
- int len, dest, tag;
327
+ int len=0, dest, tag;
289
328
  MPI_Datatype type;
290
329
  struct _Comm *comm;
291
330
 
292
- OBJ2C(rb_obj, len, buffer, type);
331
+ OBJ2C(rb_obj, len, buffer, type, 0);
293
332
  dest = NUM2INT(rb_dest);
294
333
  tag = NUM2INT(rb_tag);
295
334
  Data_Get_Struct(self, struct _Comm, comm);
@@ -301,31 +340,43 @@ static VALUE
301
340
  rb_comm_isend(VALUE self, VALUE rb_obj, VALUE rb_dest, VALUE rb_tag)
302
341
  {
303
342
  void* buffer;
304
- int len, dest, tag;
343
+ int len=0, dest, tag;
305
344
  MPI_Datatype type;
306
345
  struct _Comm *comm;
307
346
  struct _Request *request;
308
347
  VALUE rb_request;
309
348
 
310
- OBJ2C(rb_obj, len, buffer, type);
349
+ OBJ2C(rb_obj, len, buffer, type, 0);
311
350
  dest = NUM2INT(rb_dest);
312
351
  tag = NUM2INT(rb_tag);
313
352
  Data_Get_Struct(self, struct _Comm, comm);
314
353
  rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
354
+ request->free = true;
315
355
  check_error(MPI_Isend(buffer, len, type, dest, tag, comm->Comm, &(request->Request)));
316
356
 
317
357
  return rb_request;
318
358
  }
319
359
  static VALUE
320
- rb_comm_recv(VALUE self, VALUE rb_obj, VALUE rb_source, VALUE rb_tag)
360
+ rb_comm_recv(int argc, VALUE *argv, VALUE self)
321
361
  {
362
+ VALUE rb_obj, rb_source, rb_tag;
363
+ VALUE rb_len, rb_offset; // option
322
364
  void* buffer;
323
- int len, source, tag;
365
+ int source, tag, len = 0, offset = 0;
324
366
  MPI_Datatype type;
325
367
  MPI_Status *status;
326
368
  struct _Comm *comm;
327
369
 
328
- OBJ2C(rb_obj, len, buffer, type);
370
+ rb_scan_args(argc, argv, "32", &rb_obj, &rb_source, &rb_tag, &rb_len, &rb_offset);
371
+
372
+ if (rb_len != Qnil) {
373
+ len = NUM2INT(rb_len);
374
+ }
375
+ if (rb_offset != Qnil) {
376
+ offset = NUM2INT(rb_offset);
377
+ }
378
+
379
+ OBJ2C(rb_obj, len, buffer, type, offset);
329
380
  source = NUM2INT(rb_source);
330
381
  tag = NUM2INT(rb_tag);
331
382
 
@@ -336,20 +387,33 @@ rb_comm_recv(VALUE self, VALUE rb_obj, VALUE rb_source, VALUE rb_tag)
336
387
  return Data_Wrap_Struct(cStatus, NULL, Status_free, status);
337
388
  }
338
389
  static VALUE
339
- rb_comm_irecv(VALUE self, VALUE rb_obj, VALUE rb_source, VALUE rb_tag)
390
+ rb_comm_irecv(int argc, VALUE *argv, VALUE self)
340
391
  {
392
+ VALUE rb_obj, rb_source, rb_tag;
393
+ VALUE rb_len, rb_offset; // option
341
394
  void* buffer;
342
- int len, source, tag;
395
+ int source, tag, len = 0, offset = 0;
343
396
  MPI_Datatype type;
344
397
  struct _Comm *comm;
345
398
  struct _Request *request;
346
399
  VALUE rb_request;
347
400
 
348
- OBJ2C(rb_obj, len, buffer, type);
401
+ rb_scan_args(argc, argv, "32", &rb_obj, &rb_source, &rb_tag, &rb_len, &rb_offset);
402
+
403
+ if (rb_len != Qnil) {
404
+ len = NUM2INT(rb_len);
405
+ }
406
+ if (rb_offset != Qnil) {
407
+ offset = NUM2INT(rb_offset);
408
+ }
409
+
410
+ OBJ2C(rb_obj, len, buffer, type, offset);
349
411
  source = NUM2INT(rb_source);
350
412
  tag = NUM2INT(rb_tag);
413
+
351
414
  Data_Get_Struct(self, struct _Comm, comm);
352
415
  rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
416
+ request->free = true;
353
417
  check_error(MPI_Irecv(buffer, len, type, source, tag, comm->Comm, &(request->Request)));
354
418
 
355
419
  return rb_request;
@@ -358,17 +422,17 @@ static VALUE
358
422
  rb_comm_gather(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_root)
359
423
  {
360
424
  void *sendbuf, *recvbuf = NULL;
361
- int sendcount, recvcount = 0;
362
- MPI_Datatype sendtype, recvtype = NULL;
425
+ int sendcount=0, recvcount = 0;
426
+ MPI_Datatype sendtype, recvtype = 0;
363
427
  int root, rank, size;
364
428
  struct _Comm *comm;
365
- OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype);
429
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
366
430
  root = NUM2INT(rb_root);
367
431
  Data_Get_Struct(self, struct _Comm, comm);
368
432
  check_error(MPI_Comm_rank(comm->Comm, &rank));
369
433
  check_error(MPI_Comm_size(comm->Comm, &size));
370
434
  if (rank == root) {
371
- OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype);
435
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
372
436
  if (recvcount < sendcount*size)
373
437
  rb_raise(rb_eArgError, "recvbuf is too small");
374
438
  recvcount = sendcount;
@@ -380,15 +444,15 @@ static VALUE
380
444
  rb_comm_allgather(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf)
381
445
  {
382
446
  void *sendbuf, *recvbuf;
383
- int sendcount, recvcount;
447
+ int sendcount=0, recvcount=0;
384
448
  MPI_Datatype sendtype, recvtype;
385
449
  int rank, size;
386
450
  struct _Comm *comm;
387
- OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype);
451
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
388
452
  Data_Get_Struct(self, struct _Comm, comm);
389
453
  check_error(MPI_Comm_rank(comm->Comm, &rank));
390
454
  check_error(MPI_Comm_size(comm->Comm, &size));
391
- OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype);
455
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
392
456
  if (recvcount < sendcount*size)
393
457
  rb_raise(rb_eArgError, "recvbuf is too small");
394
458
  recvcount = sendcount;
@@ -399,11 +463,11 @@ static VALUE
399
463
  rb_comm_bcast(VALUE self, VALUE rb_buffer, VALUE rb_root)
400
464
  {
401
465
  void *buffer;
402
- int count;
466
+ int count=0;
403
467
  MPI_Datatype type;
404
468
  int root;
405
469
  struct _Comm *comm;
406
- OBJ2C(rb_buffer, count, buffer, type);
470
+ OBJ2C(rb_buffer, count, buffer, type, 0);
407
471
  root = NUM2INT(rb_root);
408
472
  Data_Get_Struct(self, struct _Comm, comm);
409
473
  check_error(MPI_Bcast(buffer, count, type, root, comm->Comm));
@@ -413,17 +477,17 @@ static VALUE
413
477
  rb_comm_scatter(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_root)
414
478
  {
415
479
  void *sendbuf = NULL, *recvbuf;
416
- int sendcount = 0, recvcount;
417
- MPI_Datatype sendtype = NULL, recvtype;
480
+ int sendcount = 0, recvcount=0;
481
+ MPI_Datatype sendtype = 0, recvtype;
418
482
  int root, rank, size;
419
483
  struct _Comm *comm;
420
- OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype);
484
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
421
485
  root = NUM2INT(rb_root);
422
486
  Data_Get_Struct(self, struct _Comm, comm);
423
487
  check_error(MPI_Comm_rank(comm->Comm, &rank));
424
488
  check_error(MPI_Comm_size(comm->Comm, &size));
425
489
  if (rank == root) {
426
- OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype);
490
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
427
491
  if (sendcount > recvcount*size)
428
492
  rb_raise(rb_eArgError, "recvbuf is too small");
429
493
  sendcount = recvcount;
@@ -435,17 +499,17 @@ static VALUE
435
499
  rb_comm_sendrecv(VALUE self, VALUE rb_sendbuf, VALUE rb_dest, VALUE rb_sendtag, VALUE rb_recvbuf, VALUE rb_source, VALUE rb_recvtag)
436
500
  {
437
501
  void *sendbuf, *recvbuf;
438
- int sendcount, recvcount;
502
+ int sendcount=0, recvcount=0;
439
503
  MPI_Datatype sendtype, recvtype;
440
504
  int dest, source;
441
505
  int sendtag, recvtag;
442
506
  int size;
443
507
  struct _Comm *comm;
444
508
  MPI_Status *status;
445
- OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype);
509
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
446
510
  Data_Get_Struct(self, struct _Comm, comm);
447
511
  check_error(MPI_Comm_size(comm->Comm, &size));
448
- OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype);
512
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
449
513
  dest = NUM2INT(rb_dest);
450
514
  source = NUM2INT(rb_source);
451
515
  sendtag = NUM2INT(rb_sendtag);
@@ -458,14 +522,14 @@ static VALUE
458
522
  rb_comm_alltoall(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf)
459
523
  {
460
524
  void *sendbuf, *recvbuf;
461
- int sendcount, recvcount;
525
+ int sendcount=0, recvcount=0;
462
526
  MPI_Datatype sendtype, recvtype;
463
527
  int size;
464
528
  struct _Comm *comm;
465
- OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype);
529
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
466
530
  Data_Get_Struct(self, struct _Comm, comm);
467
531
  check_error(MPI_Comm_size(comm->Comm, &size));
468
- OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype);
532
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
469
533
  if (recvcount < sendcount)
470
534
  rb_raise(rb_eArgError, "recvbuf is too small");
471
535
  recvcount = recvcount/size;
@@ -477,18 +541,18 @@ static VALUE
477
541
  rb_comm_reduce(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op, VALUE rb_root)
478
542
  {
479
543
  void *sendbuf, *recvbuf = NULL;
480
- int sendcount, recvcount = 0;
481
- MPI_Datatype sendtype, recvtype = NULL;
544
+ int sendcount=0, recvcount = 0;
545
+ MPI_Datatype sendtype, recvtype = 0;
482
546
  int root, rank, size;
483
547
  struct _Comm *comm;
484
548
  struct _Op *op;
485
- OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype);
549
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
486
550
  root = NUM2INT(rb_root);
487
551
  Data_Get_Struct(self, struct _Comm, comm);
488
552
  check_error(MPI_Comm_rank(comm->Comm, &rank));
489
553
  check_error(MPI_Comm_size(comm->Comm, &size));
490
554
  if (rank == root) {
491
- OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype);
555
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
492
556
  if (recvcount != sendcount)
493
557
  rb_raise(rb_eArgError, "sendbuf and recvbuf has the same length");
494
558
  if (recvtype != sendtype)
@@ -502,16 +566,16 @@ static VALUE
502
566
  rb_comm_allreduce(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
503
567
  {
504
568
  void *sendbuf, *recvbuf;
505
- int sendcount, recvcount;
569
+ int sendcount=0, recvcount=0;
506
570
  MPI_Datatype sendtype, recvtype;
507
571
  int rank, size;
508
572
  struct _Comm *comm;
509
573
  struct _Op *op;
510
- OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype);
574
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
511
575
  Data_Get_Struct(self, struct _Comm, comm);
512
576
  check_error(MPI_Comm_rank(comm->Comm, &rank));
513
577
  check_error(MPI_Comm_size(comm->Comm, &size));
514
- OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype);
578
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
515
579
  if (recvcount != sendcount)
516
580
  rb_raise(rb_eArgError, "sendbuf and recvbuf has the same length");
517
581
  if (recvtype != sendtype)
@@ -529,7 +593,8 @@ rb_comm_get_Errhandler(VALUE self)
529
593
 
530
594
  Data_Get_Struct(self, struct _Comm, comm);
531
595
  rb_errhandler = Data_Make_Struct(cErrhandler, struct _Errhandler, NULL, Errhandler_free, errhandler);
532
- MPI_Comm_get_errhandler(comm->Comm, &(errhandler->Errhandler));
596
+ errhandler->free = false;
597
+ check_error(MPI_Comm_get_errhandler(comm->Comm, &(errhandler->Errhandler)));
533
598
  return rb_errhandler;
534
599
  }
535
600
  static VALUE
@@ -540,7 +605,7 @@ rb_comm_set_Errhandler(VALUE self, VALUE rb_errhandler)
540
605
 
541
606
  Data_Get_Struct(self, struct _Comm, comm);
542
607
  Data_Get_Struct(rb_errhandler, struct _Errhandler, errhandler);
543
- MPI_Comm_set_errhandler(comm->Comm, errhandler->Errhandler);
608
+ check_error(MPI_Comm_set_errhandler(comm->Comm, errhandler->Errhandler));
544
609
  return self;
545
610
  }
546
611
  static VALUE
@@ -607,6 +672,7 @@ void Init_mpi()
607
672
  mMPI = rb_define_module("MPI");
608
673
  rb_define_module_function(mMPI, "Init", rb_m_init, -1);
609
674
  rb_define_module_function(mMPI, "Finalize", rb_m_finalize, -1);
675
+ rb_define_module_function(mMPI, "Abort", rb_m_abort, 2);
610
676
  rb_define_const(mMPI, "VERSION", INT2NUM(MPI_VERSION));
611
677
  rb_define_const(mMPI, "SUBVERSION", INT2NUM(MPI_SUBVERSION));
612
678
  rb_define_const(mMPI, "SUCCESS", INT2NUM(MPI_SUCCESS));
@@ -620,8 +686,8 @@ void Init_mpi()
620
686
  rb_define_method(cComm, "size", rb_comm_size, 0);
621
687
  rb_define_method(cComm, "Send", rb_comm_send, 3);
622
688
  rb_define_method(cComm, "Isend", rb_comm_isend, 3);
623
- rb_define_method(cComm, "Recv", rb_comm_recv, 3);
624
- rb_define_method(cComm, "Irecv", rb_comm_irecv, 3);
689
+ rb_define_method(cComm, "Recv", rb_comm_recv, -1);
690
+ rb_define_method(cComm, "Irecv", rb_comm_irecv, -1);
625
691
  rb_define_method(cComm, "Gather", rb_comm_gather, 3);
626
692
  rb_define_method(cComm, "Allgather", rb_comm_allgather, 2);
627
693
  rb_define_method(cComm, "Bcast", rb_comm_bcast, 2);
data/lib/mpi/utils.rb ADDED
@@ -0,0 +1,17 @@
1
+ module MPI
2
+
3
+ module_function
4
+
5
+ def task_divide(m, size)
6
+ dm = m.to_f/size
7
+ ary = Array.new(size)
8
+ ary[0] = dm.round
9
+ sum = ary[0]
10
+ (size-1).times do|i|
11
+ ary[i+1] = (dm*(i+2)).round - sum
12
+ sum += ary[i+1]
13
+ end
14
+ ary
15
+ end
16
+
17
+ end # module MPI
data/samples/hello.rb CHANGED
@@ -4,13 +4,19 @@ MPI.Init
4
4
 
5
5
 
6
6
  world = MPI::Comm::WORLD
7
+
8
+ if world.size == 1
9
+ print "Size is one, so do nothing\n"
10
+ exit
11
+ end
12
+
7
13
  rank = world.rank
8
14
 
9
15
  if rank == 0
10
16
  (world.size-1).times do |i|
11
17
  str ="\x00"*100
12
18
  world.Recv(str, i+1, 0)
13
- p str
19
+ p str.gsub(/\000/,"")
14
20
  end
15
21
  else
16
22
  message = "Hello from #{rank}"
data/samples/narray.rb CHANGED
@@ -4,6 +4,12 @@ MPI.Init
4
4
 
5
5
 
6
6
  world = MPI::Comm::WORLD
7
+
8
+ if world.size == 1
9
+ print "Size is one, so do nothing\n"
10
+ exit
11
+ end
12
+
7
13
  rank = world.rank
8
14
 
9
15
  if rank == 0
@@ -0,0 +1,29 @@
1
+ require "mpi"
2
+
3
+ MPI.Init
4
+
5
+
6
+ world = MPI::Comm::WORLD
7
+
8
+ if world.size == 1
9
+ print "Size is one, so do nothing\n"
10
+ exit
11
+ end
12
+
13
+ rank = world.rank
14
+ size = world.size
15
+
16
+ length = 2
17
+ if rank == 0
18
+ a = NArray.float(length,size-1)
19
+ (size-1).times do |i|
20
+ world.Recv(a, i+1, 1, length, i*length)
21
+ end
22
+ p a
23
+ else
24
+ a = NArray.float(length).indgen + rank*10
25
+ world.Send(a, 0, 1)
26
+ end
27
+
28
+
29
+ MPI.Finalize
@@ -34,14 +34,13 @@ describe "MPI" do
34
34
  status = @world.Recv(str, i+1, tag)
35
35
  status.source.should eql(i+1)
36
36
  status.tag.should eql(tag)
37
- status.error.should eq(MPI::SUCCESS)
38
37
  str.should match(/\AHello from #{i+1}/)
39
38
  end
40
39
  end
41
40
  end
42
41
 
43
42
  it "should send and receive NArray" do
44
- tag = 0
43
+ tag = 1
45
44
  rank = @world.rank
46
45
  [NArray[1,2,3], NArray[3.0,2.0,1.0]].each do |ary0|
47
46
  ary0 = NArray[1,2,3]
@@ -52,7 +51,6 @@ describe "MPI" do
52
51
  status = @world.Recv(ary1, i+1, tag)
53
52
  status.source.should eql(i+1)
54
53
  status.tag.should eql(tag)
55
- status.error.should eq(MPI::SUCCESS)
56
54
  ary1.should == ary0
57
55
  end
58
56
  end
@@ -60,14 +58,12 @@ describe "MPI" do
60
58
  end
61
59
 
62
60
  it "should send and receive without blocking" do
63
- tag = 0
61
+ tag = 2
64
62
  rank = @world.rank
65
63
  message = "Hello from #{rank}"
66
64
  if rank != 0
67
65
  request = @world.Isend(message, 0, tag)
68
66
  status = request.Wait
69
- # status.source.should eql(rank)
70
- status.tag.should eql(tag)
71
67
  end
72
68
  if rank == 0
73
69
  (@world.size-1).times do |i|
@@ -0,0 +1,21 @@
1
+ require "test/unit"
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
4
+ require "mpi/utils"
5
+
6
+ class TestMPIUtils < Test::Unit::TestCase
7
+
8
+ def setup
9
+ end
10
+
11
+ def teardown
12
+ end
13
+
14
+ def test_task_divide
15
+ [[4,1], [6,3], [7,3], [15,4], [3, 7]].each do |m, size|
16
+ ary = MPI.task_divide(m, size)
17
+ assert ary.max-ary.min <= 1
18
+ end
19
+ end
20
+
21
+ end
metadata CHANGED
@@ -1,86 +1,98 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ruby-mpi
3
- version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.2.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
6
5
  platform: ruby
7
- authors:
6
+ authors:
8
7
  - Seiya Nishizawa
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
-
13
- date: 2011-04-22 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
11
+ date: 2014-05-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
16
14
  name: rspec
17
- requirement: &id001 !ruby/object:Gem::Requirement
18
- none: false
19
- requirements:
20
- - - ~>
21
- - !ruby/object:Gem::Version
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
22
19
  version: 2.3.0
23
20
  type: :development
24
21
  prerelease: false
25
- version_requirements: *id001
26
- - !ruby/object:Gem::Dependency
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 2.3.0
27
+ - !ruby/object:Gem::Dependency
27
28
  name: bundler
28
- requirement: &id002 !ruby/object:Gem::Requirement
29
- none: false
30
- requirements:
31
- - - ~>
32
- - !ruby/object:Gem::Version
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
33
  version: 1.0.0
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *id002
37
- - !ruby/object:Gem::Dependency
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.0
41
+ - !ruby/object:Gem::Dependency
38
42
  name: jeweler
39
- requirement: &id003 !ruby/object:Gem::Requirement
40
- none: false
41
- requirements:
42
- - - ~>
43
- - !ruby/object:Gem::Version
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
44
47
  version: 1.5.2
45
48
  type: :development
46
49
  prerelease: false
47
- version_requirements: *id003
48
- - !ruby/object:Gem::Dependency
49
- name: rcov
50
- requirement: &id004 !ruby/object:Gem::Requirement
51
- none: false
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- version: "0"
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 1.5.2
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
56
62
  type: :development
57
63
  prerelease: false
58
- version_requirements: *id004
59
- - !ruby/object:Gem::Dependency
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
60
70
  name: narray
61
- requirement: &id005 !ruby/object:Gem::Requirement
62
- none: false
63
- requirements:
64
- - - ">="
65
- - !ruby/object:Gem::Version
66
- version: "0"
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
67
76
  type: :development
68
77
  prerelease: false
69
- version_requirements: *id005
70
- description: A ruby binding of Message Passing Interface (MPI), which is an API specification that allows processes to communicate with one another by sending and receiving messages.
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: A ruby binding of Message Passing Interface (MPI), which is an API specification
84
+ that allows processes to communicate with one another by sending and receiving messages.
71
85
  email: seiya@gfd-dennou.org
72
86
  executables: []
73
-
74
- extensions:
87
+ extensions:
75
88
  - ext/mpi/extconf.rb
76
- extra_rdoc_files:
89
+ extra_rdoc_files:
77
90
  - LICENSE.txt
78
91
  - README.rdoc
79
- files:
92
+ files:
80
93
  - .document
81
94
  - .rspec
82
95
  - Gemfile
83
- - Gemfile.lock
84
96
  - LICENSE.txt
85
97
  - README.rdoc
86
98
  - Rakefile
@@ -88,41 +100,36 @@ files:
88
100
  - ext/mpi/extconf.rb
89
101
  - ext/mpi/mpi.c
90
102
  - lib/mpi.rb
103
+ - lib/mpi/utils.rb
91
104
  - ruby-mpi.gemspec
92
105
  - samples/hello.rb
93
106
  - samples/narray.rb
107
+ - samples/narray_offset.rb
94
108
  - spec/ruby-mpi_spec.rb
95
109
  - spec/spec_helper.rb
110
+ - test/test_utils.rb
96
111
  homepage: http://github.com/seiya/ruby-mpi
97
- licenses:
112
+ licenses:
98
113
  - MIT
114
+ metadata: {}
99
115
  post_install_message:
100
116
  rdoc_options: []
101
-
102
- require_paths:
117
+ require_paths:
103
118
  - lib
104
- required_ruby_version: !ruby/object:Gem::Requirement
105
- none: false
106
- requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- hash: -3549605766415082841
110
- segments:
111
- - 0
112
- version: "0"
113
- required_rubygems_version: !ruby/object:Gem::Requirement
114
- none: false
115
- requirements:
116
- - - ">="
117
- - !ruby/object:Gem::Version
118
- version: "0"
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
119
129
  requirements: []
120
-
121
130
  rubyforge_project:
122
- rubygems_version: 1.7.2
131
+ rubygems_version: 2.1.11
123
132
  signing_key:
124
- specification_version: 3
133
+ specification_version: 4
125
134
  summary: A ruby binding of MPI
126
- test_files:
127
- - spec/ruby-mpi_spec.rb
128
- - spec/spec_helper.rb
135
+ test_files: []
data/Gemfile.lock DELETED
@@ -1,30 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- diff-lcs (1.1.2)
5
- git (1.2.5)
6
- jeweler (1.5.2)
7
- bundler (~> 1.0.0)
8
- git (>= 1.2.5)
9
- rake
10
- narray (0.5.9.9)
11
- rake (0.8.7)
12
- rcov (0.9.9)
13
- rspec (2.3.0)
14
- rspec-core (~> 2.3.0)
15
- rspec-expectations (~> 2.3.0)
16
- rspec-mocks (~> 2.3.0)
17
- rspec-core (2.3.1)
18
- rspec-expectations (2.3.0)
19
- diff-lcs (~> 1.1.2)
20
- rspec-mocks (2.3.0)
21
-
22
- PLATFORMS
23
- ruby
24
-
25
- DEPENDENCIES
26
- bundler (~> 1.0.0)
27
- jeweler (~> 1.5.2)
28
- narray
29
- rcov
30
- rspec (~> 2.3.0)