ruby-mpi 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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)