ruby-mpi 0.3.2 → 0.4.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.
data/ext/mpi/mpi.c CHANGED
@@ -27,6 +27,10 @@
27
27
  ---->> Please define NA_MPI_LLINT manually because sizeof(long long) != 8. <<----
28
28
  #endif
29
29
 
30
+ #ifndef NARRAY_BIGMEM
31
+ # define NA_LLINT -999
32
+ #endif
33
+
30
34
 
31
35
  #define OBJ2C(rb_obj, len, buffer, typ, off) \
32
36
  {\
@@ -313,6 +317,37 @@ rb_m_abort(VALUE self, VALUE rcomm, VALUE rerror)
313
317
  return INT2NUM(ierror);
314
318
  }
315
319
 
320
+ static VALUE
321
+ rb_m_wtime(VALUE self)
322
+ {
323
+ double time;
324
+ time = MPI_Wtime();
325
+ return rb_float_new(time);
326
+ }
327
+
328
+ static VALUE
329
+ rb_m_waitall(VALUE self, VALUE rary)
330
+ {
331
+ struct _Request *req;
332
+ MPI_Request *request;
333
+ MPI_Status *status;
334
+ VALUE rb_status;
335
+ long count, i;
336
+
337
+ count = RARRAY_LEN(rary);
338
+
339
+ request = ALLOCA_N(MPI_Request, count);
340
+ for (i=0; i<count; i++) {
341
+ Data_Get_Struct(rb_ary_entry(rary,i), struct _Request, req);
342
+ request[i] = req->Request;
343
+ }
344
+ rb_status = rb_ary_new2(count);
345
+ status = ALLOC_N(MPI_Status, count);
346
+ check_error(MPI_Waitall(count, request, status));
347
+ for (i=0; i<count; i++)
348
+ rb_ary_push(rb_status, Data_Wrap_Struct(cStatus, NULL, Status_free, &(status[i])));
349
+ return rb_status;
350
+ }
316
351
 
317
352
  // MPI::Comm
318
353
  /*
@@ -465,11 +500,124 @@ rb_comm_gather(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_root)
465
500
  if (recvcount < sendcount*size)
466
501
  rb_raise(rb_eArgError, "recvbuf is too small");
467
502
  recvcount = sendcount;
503
+ } else {
504
+ recvtype = sendtype; // to avoid segmentation fault in an environment
468
505
  }
469
506
  check_error(MPI_Gather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm->Comm));
470
507
  return Qnil;
471
508
  }
472
509
  static VALUE
510
+ rb_comm_igather(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_root)
511
+ {
512
+ void *sendbuf, *recvbuf = NULL;
513
+ int sendcount=0, recvcount = 0;
514
+ MPI_Datatype sendtype, recvtype = 0;
515
+ int root, rank, size;
516
+ struct _Comm *comm;
517
+ struct _Request *request;
518
+ VALUE rb_request;
519
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
520
+ root = NUM2INT(rb_root);
521
+ Data_Get_Struct(self, struct _Comm, comm);
522
+ check_error(MPI_Comm_rank(comm->Comm, &rank));
523
+ check_error(MPI_Comm_size(comm->Comm, &size));
524
+ if (rank == root) {
525
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
526
+ if (recvcount < sendcount*size)
527
+ rb_raise(rb_eArgError, "recvbuf is too small");
528
+ recvcount = sendcount;
529
+ } else {
530
+ recvtype = sendtype; // to avoid segmentation fault in an environment
531
+ }
532
+ rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
533
+ request->free = true;
534
+ check_error(MPI_Igather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm->Comm, &(request->Request)));
535
+ return rb_request;
536
+ }
537
+ static VALUE
538
+ rb_comm_gatherv(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_recvcounts, VALUE rb_displs, VALUE rb_root)
539
+ {
540
+ void *sendbuf, *recvbuf = NULL;
541
+ int sendcount=0, bufsize=0;
542
+ int *recvcounts = NULL, *displs = NULL;
543
+ MPI_Datatype sendtype, recvtype = 0;
544
+ int root, rank, size;
545
+ struct _Comm *comm;
546
+ int max, tmp;
547
+ int i;
548
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
549
+ root = NUM2INT(rb_root);
550
+ Data_Get_Struct(self, struct _Comm, comm);
551
+ check_error(MPI_Comm_rank(comm->Comm, &rank));
552
+ check_error(MPI_Comm_size(comm->Comm, &size));
553
+ if (rank == root) {
554
+ if ( RARRAY_LEN(rb_recvcounts) != size )
555
+ rb_raise(rb_eArgError, "length of recvcounts must be the same as the group size");
556
+ if ( RARRAY_LEN(rb_displs) != size )
557
+ rb_raise(rb_eArgError, "length of displs must be the same as the group size");
558
+ recvcounts = ALLOCA_N(int, size);
559
+ displs = ALLOCA_N(int, size);
560
+ max = 0;
561
+ for (i=0; i<size; i++) {
562
+ recvcounts[i] = NUM2INT(rb_ary_entry(rb_recvcounts,i));
563
+ displs[i] = NUM2INT(rb_ary_entry(rb_displs,i));
564
+ tmp = displs[i] + recvcounts[i];
565
+ if (tmp > max) max = tmp;
566
+ }
567
+ OBJ2C(rb_recvbuf, bufsize, recvbuf, recvtype, 0);
568
+ if (bufsize < max)
569
+ rb_raise(rb_eArgError, "recvbuf is too small");
570
+ } else {
571
+ recvtype = sendtype; // to avoid segmentation fault in an environment
572
+ }
573
+ check_error(MPI_Gatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, root, comm->Comm));
574
+ return Qnil;
575
+ }
576
+ static VALUE
577
+ rb_comm_igatherv(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_recvcounts, VALUE rb_displs, VALUE rb_root)
578
+ {
579
+ void *sendbuf, *recvbuf = NULL;
580
+ int sendcount=0, bufsize=0;
581
+ int *recvcounts = NULL, *displs = NULL;
582
+ MPI_Datatype sendtype, recvtype = 0;
583
+ int root, rank, size;
584
+ struct _Comm *comm;
585
+ struct _Request *request;
586
+ VALUE rb_request;
587
+ int max, tmp;
588
+ int i;
589
+
590
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
591
+ root = NUM2INT(rb_root);
592
+ Data_Get_Struct(self, struct _Comm, comm);
593
+ check_error(MPI_Comm_rank(comm->Comm, &rank));
594
+ check_error(MPI_Comm_size(comm->Comm, &size));
595
+ if (rank == root) {
596
+ recvcounts = ALLOCA_N(int, size);
597
+ displs = ALLOCA_N(int, size);
598
+ max = 0;
599
+ if ( RARRAY_LEN(rb_recvcounts) != size )
600
+ rb_raise(rb_eArgError, "length of recvcounts must be the same as the group size");
601
+ if ( RARRAY_LEN(rb_displs) != size )
602
+ rb_raise(rb_eArgError, "length of displs must be the same as the group size");
603
+ for (i=0; i<size; i++) {
604
+ recvcounts[i] = NUM2INT(rb_ary_entry(rb_recvcounts,i));
605
+ displs[i] = NUM2INT(rb_ary_entry(rb_displs,i));
606
+ tmp = displs[i] + recvcounts[i];
607
+ if (tmp > max) max = tmp;
608
+ }
609
+ OBJ2C(rb_recvbuf, bufsize, recvbuf, recvtype, 0);
610
+ if (bufsize < max)
611
+ rb_raise(rb_eArgError, "recvbuf is too small");
612
+ } else {
613
+ recvtype = sendtype; // to avoid segmentation fault in an environment
614
+ }
615
+ rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
616
+ request->free = true;
617
+ check_error(MPI_Igatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, root, comm->Comm, &(request->Request)));
618
+ return rb_request;
619
+ }
620
+ static VALUE
473
621
  rb_comm_allgather(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf)
474
622
  {
475
623
  void *sendbuf, *recvbuf;
@@ -489,6 +637,105 @@ rb_comm_allgather(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf)
489
637
  return Qnil;
490
638
  }
491
639
  static VALUE
640
+ rb_comm_iallgather(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf)
641
+ {
642
+ void *sendbuf, *recvbuf;
643
+ int sendcount=0, recvcount=0;
644
+ MPI_Datatype sendtype, recvtype;
645
+ int rank, size;
646
+ struct _Comm *comm;
647
+ struct _Request *request;
648
+ VALUE rb_request;
649
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
650
+ Data_Get_Struct(self, struct _Comm, comm);
651
+ check_error(MPI_Comm_rank(comm->Comm, &rank));
652
+ check_error(MPI_Comm_size(comm->Comm, &size));
653
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
654
+ if (recvcount < sendcount*size)
655
+ rb_raise(rb_eArgError, "recvbuf is too small");
656
+ recvcount = sendcount;
657
+ rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
658
+ request->free = true;
659
+ check_error(MPI_Iallgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm->Comm, &(request->Request)));
660
+ return rb_request;
661
+ }
662
+ static VALUE
663
+ rb_comm_allgatherv(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_recvcounts, VALUE rb_displs)
664
+ {
665
+ void *sendbuf, *recvbuf;
666
+ int sendcount=0, bufsize=0;
667
+ int *recvcounts, *displs;
668
+ MPI_Datatype sendtype, recvtype;
669
+ int rank, size;
670
+ struct _Comm *comm;
671
+ int max, tmp;
672
+ int i;
673
+ Data_Get_Struct(self, struct _Comm, comm);
674
+ check_error(MPI_Comm_rank(comm->Comm, &rank));
675
+ check_error(MPI_Comm_size(comm->Comm, &size));
676
+ if ( RARRAY_LEN(rb_recvcounts) != size )
677
+ rb_raise(rb_eArgError, "length of recvcounts must be the same as the group size");
678
+ if ( RARRAY_LEN(rb_displs) != size )
679
+ rb_raise(rb_eArgError, "length of displs must be the same as the group size");
680
+ recvcounts = ALLOCA_N(int, size);
681
+ displs = ALLOCA_N(int, size);
682
+ max = 0;
683
+ for (i=0; i<size; i++) {
684
+ recvcounts[i] = NUM2INT(rb_ary_entry(rb_recvcounts,i));
685
+ displs[i] = NUM2INT(rb_ary_entry(rb_displs,i));
686
+ tmp = displs[i] + recvcounts[i];
687
+ if (tmp > max) max = tmp;
688
+ }
689
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
690
+ if (sendcount != recvcounts[rank])
691
+ rb_raise(rb_eArgError, "length of sendbuf is not the same as recvcounts[rank]");
692
+ OBJ2C(rb_recvbuf, bufsize, recvbuf, recvtype, 0);
693
+ if (bufsize < max)
694
+ rb_raise(rb_eArgError, "recvbuf is too small");
695
+ check_error(MPI_Allgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm->Comm));
696
+ return Qnil;
697
+ }
698
+ static VALUE
699
+ rb_comm_iallgatherv(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_recvcounts, VALUE rb_displs)
700
+ {
701
+ void *sendbuf, *recvbuf;
702
+ int sendcount=0, bufsize=0;
703
+ int *recvcounts, *displs;
704
+ MPI_Datatype sendtype, recvtype;
705
+ int rank, size;
706
+ struct _Comm *comm;
707
+ struct _Request *request;
708
+ VALUE rb_request;
709
+ int max, tmp;
710
+ int i;
711
+ Data_Get_Struct(self, struct _Comm, comm);
712
+ check_error(MPI_Comm_rank(comm->Comm, &rank));
713
+ check_error(MPI_Comm_size(comm->Comm, &size));
714
+ if ( RARRAY_LEN(rb_recvcounts) != size )
715
+ rb_raise(rb_eArgError, "length of recvcounts must be the same as the group size");
716
+ if ( RARRAY_LEN(rb_displs) != size )
717
+ rb_raise(rb_eArgError, "length of displs must be the same as the group size");
718
+ recvcounts = ALLOCA_N(int, size);
719
+ displs = ALLOCA_N(int, size);
720
+ max = 0;
721
+ for (i=0; i<size; i++) {
722
+ recvcounts[i] = NUM2INT(rb_ary_entry(rb_recvcounts,i));
723
+ displs[i] = NUM2INT(rb_ary_entry(rb_displs,i));
724
+ tmp = displs[i] + recvcounts[i];
725
+ if (tmp > max) max = tmp;
726
+ }
727
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
728
+ if (sendcount != recvcounts[rank])
729
+ rb_raise(rb_eArgError, "length of sendbuf is not the same as recvcounts[rank]");
730
+ OBJ2C(rb_recvbuf, bufsize, recvbuf, recvtype, 0);
731
+ if (bufsize < max)
732
+ rb_raise(rb_eArgError, "recvbuf is too small");
733
+ rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
734
+ request->free = true;
735
+ check_error(MPI_Iallgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm->Comm, &(request->Request)));
736
+ return rb_request;
737
+ }
738
+ static VALUE
492
739
  rb_comm_bcast(VALUE self, VALUE rb_buffer, VALUE rb_root)
493
740
  {
494
741
  void *buffer;
@@ -503,6 +750,24 @@ rb_comm_bcast(VALUE self, VALUE rb_buffer, VALUE rb_root)
503
750
  return Qnil;
504
751
  }
505
752
  static VALUE
753
+ rb_comm_ibcast(VALUE self, VALUE rb_buffer, VALUE rb_root)
754
+ {
755
+ void *buffer;
756
+ int count=0;
757
+ MPI_Datatype type;
758
+ int root;
759
+ struct _Comm *comm;
760
+ struct _Request *request;
761
+ VALUE rb_request;
762
+ OBJ2C(rb_buffer, count, buffer, type, 0);
763
+ root = NUM2INT(rb_root);
764
+ Data_Get_Struct(self, struct _Comm, comm);
765
+ rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
766
+ request->free = true;
767
+ check_error(MPI_Ibcast(buffer, count, type, root, comm->Comm, &(request->Request)));
768
+ return rb_request;
769
+ }
770
+ static VALUE
506
771
  rb_comm_scatter(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_root)
507
772
  {
508
773
  void *sendbuf = NULL, *recvbuf;
@@ -525,6 +790,110 @@ rb_comm_scatter(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_root)
525
790
  return Qnil;
526
791
  }
527
792
  static VALUE
793
+ rb_comm_iscatter(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_root)
794
+ {
795
+ void *sendbuf = NULL, *recvbuf;
796
+ int sendcount = 0, recvcount=0;
797
+ MPI_Datatype sendtype = 0, recvtype;
798
+ int root, rank, size;
799
+ struct _Comm *comm;
800
+ struct _Request *request;
801
+ VALUE rb_request;
802
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
803
+ root = NUM2INT(rb_root);
804
+ Data_Get_Struct(self, struct _Comm, comm);
805
+ check_error(MPI_Comm_rank(comm->Comm, &rank));
806
+ check_error(MPI_Comm_size(comm->Comm, &size));
807
+ if (rank == root) {
808
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
809
+ if (sendcount > recvcount*size)
810
+ rb_raise(rb_eArgError, "recvbuf is too small");
811
+ sendcount = recvcount;
812
+ }
813
+ rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
814
+ request->free = true;
815
+ check_error(MPI_Iscatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm->Comm, &(request->Request)));
816
+ return rb_request;
817
+ }
818
+ static VALUE
819
+ rb_comm_scatterv(VALUE self, VALUE rb_sendbuf, VALUE rb_sendcounts, VALUE rb_displs, VALUE rb_recvbuf, VALUE rb_root)
820
+ {
821
+ void *sendbuf = NULL, *recvbuf;
822
+ int recvcount = 0, bufsize=0;
823
+ int *sendcounts, *displs;
824
+ MPI_Datatype sendtype = 0, recvtype;
825
+ int root, rank, size;
826
+ struct _Comm *comm;
827
+ int max, tmp;
828
+ int i;
829
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
830
+ root = NUM2INT(rb_root);
831
+ Data_Get_Struct(self, struct _Comm, comm);
832
+ check_error(MPI_Comm_rank(comm->Comm, &rank));
833
+ check_error(MPI_Comm_size(comm->Comm, &size));
834
+ if (rank == root) {
835
+ if ( RARRAY_LEN(rb_sendcounts) != size )
836
+ rb_raise(rb_eArgError, "length of sendcounts must be the same as the group size");
837
+ if ( RARRAY_LEN(rb_displs) != size )
838
+ rb_raise(rb_eArgError, "length of displs must be the same as the group size");
839
+ sendcounts = ALLOCA_N(int, size);
840
+ displs = ALLOCA_N(int, size);
841
+ max = 0;
842
+ for (i=0; i<size; i++) {
843
+ sendcounts[i] = NUM2INT(rb_ary_entry(rb_sendcounts,i));
844
+ displs[i] = NUM2INT(rb_ary_entry(rb_displs,i));
845
+ tmp = displs[i] + sendcounts[i];
846
+ if (tmp > max) max = tmp;
847
+ }
848
+ OBJ2C(rb_sendbuf, bufsize, sendbuf, sendtype, 0);
849
+ if (bufsize < max)
850
+ rb_raise(rb_eArgError, "sendbuf is too small");
851
+ }
852
+ check_error(MPI_Scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm->Comm));
853
+ return Qnil;
854
+ }
855
+ static VALUE
856
+ rb_comm_iscatterv(VALUE self, VALUE rb_sendbuf, VALUE rb_sendcounts, VALUE rb_displs, VALUE rb_recvbuf, VALUE rb_root)
857
+ {
858
+ void *sendbuf = NULL, *recvbuf;
859
+ int recvcount = 0, bufsize=0;
860
+ int *sendcounts, *displs;
861
+ MPI_Datatype sendtype = 0, recvtype;
862
+ int root, rank, size;
863
+ struct _Comm *comm;
864
+ struct _Request *request;
865
+ VALUE rb_request;
866
+ int max, tmp;
867
+ int i;
868
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
869
+ root = NUM2INT(rb_root);
870
+ Data_Get_Struct(self, struct _Comm, comm);
871
+ check_error(MPI_Comm_rank(comm->Comm, &rank));
872
+ check_error(MPI_Comm_size(comm->Comm, &size));
873
+ if (rank == root) {
874
+ if ( RARRAY_LEN(rb_sendcounts) != size )
875
+ rb_raise(rb_eArgError, "length of sendcounts must be the same as the group size");
876
+ if ( RARRAY_LEN(rb_displs) != size )
877
+ rb_raise(rb_eArgError, "length of displs must be the same as the group size");
878
+ sendcounts = ALLOCA_N(int, size);
879
+ displs = ALLOCA_N(int, size);
880
+ max = 0;
881
+ for (i=0; i<size; i++) {
882
+ sendcounts[i] = NUM2INT(rb_ary_entry(rb_sendcounts,i));
883
+ displs[i] = NUM2INT(rb_ary_entry(rb_displs,i));
884
+ tmp = displs[i] + sendcounts[i];
885
+ if (tmp > max) max = tmp;
886
+ }
887
+ OBJ2C(rb_sendbuf, bufsize, sendbuf, sendtype, 0);
888
+ if (bufsize < max)
889
+ rb_raise(rb_eArgError, "sendbuf is too small");
890
+ }
891
+ rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
892
+ request->free = true;
893
+ check_error(MPI_Iscatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm->Comm, &(request->Request)));
894
+ return rb_request;
895
+ }
896
+ static VALUE
528
897
  rb_comm_sendrecv(VALUE self, VALUE rb_sendbuf, VALUE rb_dest, VALUE rb_sendtag, VALUE rb_recvbuf, VALUE rb_source, VALUE rb_recvtag)
529
898
  {
530
899
  void *sendbuf, *recvbuf;
@@ -567,6 +936,129 @@ rb_comm_alltoall(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf)
567
936
  return Qnil;
568
937
  }
569
938
  static VALUE
939
+ rb_comm_ialltoall(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf)
940
+ {
941
+ void *sendbuf, *recvbuf;
942
+ int sendcount=0, recvcount=0;
943
+ MPI_Datatype sendtype, recvtype;
944
+ int size;
945
+ struct _Comm *comm;
946
+ struct _Request *request;
947
+ VALUE rb_request;
948
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
949
+ Data_Get_Struct(self, struct _Comm, comm);
950
+ check_error(MPI_Comm_size(comm->Comm, &size));
951
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
952
+ if (recvcount < sendcount)
953
+ rb_raise(rb_eArgError, "recvbuf is too small");
954
+ recvcount = recvcount/size;
955
+ sendcount = sendcount/size;
956
+ rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
957
+ request->free = true;
958
+ check_error(MPI_Ialltoall(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm->Comm, &(request->Request)));
959
+ return rb_request;
960
+ }
961
+ static VALUE
962
+ rb_comm_alltoallv(VALUE self, VALUE rb_sendbuf, VALUE rb_sendcounts, VALUE rb_sdispls, VALUE rb_recvbuf, VALUE rb_recvcounts, VALUE rb_rdispls)
963
+ {
964
+ void *sendbuf, *recvbuf;
965
+ int bufsize=0;
966
+ int *sendcounts, *sdispls;
967
+ int *recvcounts, *rdispls;
968
+ MPI_Datatype sendtype, recvtype;
969
+ int size;
970
+ struct _Comm *comm;
971
+ int smax, rmax, tmp;
972
+ int i;
973
+ Data_Get_Struct(self, struct _Comm, comm);
974
+ check_error(MPI_Comm_size(comm->Comm, &size));
975
+ if ( RARRAY_LEN(rb_sendcounts) != size )
976
+ rb_raise(rb_eArgError, "length of sendcounts must be the same as the group size");
977
+ if ( RARRAY_LEN(rb_sdispls) != size )
978
+ rb_raise(rb_eArgError, "length of sdispls must be the same as the group size");
979
+ if ( RARRAY_LEN(rb_recvcounts) != size )
980
+ rb_raise(rb_eArgError, "length of recvcounts must be the same as the group size");
981
+ if ( RARRAY_LEN(rb_rdispls) != size )
982
+ rb_raise(rb_eArgError, "length of rdispls must be the same as the group size");
983
+ sendcounts = ALLOCA_N(int, size);
984
+ sdispls = ALLOCA_N(int, size);
985
+ recvcounts = ALLOCA_N(int, size);
986
+ rdispls = ALLOCA_N(int, size);
987
+ smax = 0;
988
+ rmax = 0;
989
+ for (i=0; i<size; i++) {
990
+ sendcounts[i] = NUM2INT(rb_ary_entry(rb_sendcounts,i));
991
+ sdispls[i] = NUM2INT(rb_ary_entry(rb_sdispls,i));
992
+ recvcounts[i] = NUM2INT(rb_ary_entry(rb_recvcounts,i));
993
+ rdispls[i] = NUM2INT(rb_ary_entry(rb_rdispls,i));
994
+ tmp = sdispls[i] + sendcounts[i];
995
+ if(tmp > smax) smax = tmp;
996
+ tmp = rdispls[i] + recvcounts[i];
997
+ if(tmp > rmax) rmax = tmp;
998
+ }
999
+ OBJ2C(rb_sendbuf, bufsize, sendbuf, sendtype, 0);
1000
+ if (bufsize < smax)
1001
+ rb_raise(rb_eArgError, "sendbuf is too small");
1002
+ bufsize = 0;
1003
+ OBJ2C(rb_recvbuf, bufsize, recvbuf, recvtype, 0);
1004
+ if (bufsize < rmax)
1005
+ rb_raise(rb_eArgError, "recvbuf is too small");
1006
+ check_error(MPI_Alltoallv(sendbuf, sendcounts, sdispls, sendtype, recvbuf, recvcounts, rdispls, recvtype, comm->Comm));
1007
+ return Qnil;
1008
+ }
1009
+ static VALUE
1010
+ rb_comm_ialltoallv(VALUE self, VALUE rb_sendbuf, VALUE rb_sendcounts, VALUE rb_sdispls, VALUE rb_recvbuf, VALUE rb_recvcounts, VALUE rb_rdispls)
1011
+ {
1012
+ void *sendbuf, *recvbuf;
1013
+ int bufsize=0;
1014
+ int *sendcounts, *sdispls;
1015
+ int *recvcounts, *rdispls;
1016
+ MPI_Datatype sendtype, recvtype;
1017
+ int size;
1018
+ struct _Comm *comm;
1019
+ struct _Request *request;
1020
+ VALUE rb_request;
1021
+ int smax, rmax, tmp;
1022
+ int i;
1023
+ Data_Get_Struct(self, struct _Comm, comm);
1024
+ check_error(MPI_Comm_size(comm->Comm, &size));
1025
+ if ( RARRAY_LEN(rb_sendcounts) != size )
1026
+ rb_raise(rb_eArgError, "length of sendcounts must be the same as the group size");
1027
+ if ( RARRAY_LEN(rb_sdispls) != size )
1028
+ rb_raise(rb_eArgError, "length of sdispls must be the same as the group size");
1029
+ if ( RARRAY_LEN(rb_recvcounts) != size )
1030
+ rb_raise(rb_eArgError, "length of recvcounts must be the same as the group size");
1031
+ if ( RARRAY_LEN(rb_rdispls) != size )
1032
+ rb_raise(rb_eArgError, "length of rdispls must be the same as the group size");
1033
+ sendcounts = ALLOCA_N(int, size);
1034
+ sdispls = ALLOCA_N(int, size);
1035
+ recvcounts = ALLOCA_N(int, size);
1036
+ rdispls = ALLOCA_N(int, size);
1037
+ smax = 0;
1038
+ rmax = 0;
1039
+ for (i=0; i<size; i++) {
1040
+ sendcounts[i] = NUM2INT(rb_ary_entry(rb_sendcounts,i));
1041
+ sdispls[i] = NUM2INT(rb_ary_entry(rb_sdispls,i));
1042
+ recvcounts[i] = NUM2INT(rb_ary_entry(rb_recvcounts,i));
1043
+ rdispls[i] = NUM2INT(rb_ary_entry(rb_rdispls,i));
1044
+ tmp = sdispls[i] + sendcounts[i];
1045
+ if(tmp > smax) smax = tmp;
1046
+ tmp = rdispls[i] + recvcounts[i];
1047
+ if(tmp > rmax) rmax = tmp;
1048
+ }
1049
+ OBJ2C(rb_sendbuf, bufsize, sendbuf, sendtype, 0);
1050
+ if (bufsize < smax)
1051
+ rb_raise(rb_eArgError, "sendbuf is too small");
1052
+ bufsize = 0;
1053
+ OBJ2C(rb_recvbuf, bufsize, recvbuf, recvtype, 0);
1054
+ if (bufsize < rmax)
1055
+ rb_raise(rb_eArgError, "recvbuf is too small");
1056
+ rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
1057
+ request->free = true;
1058
+ check_error(MPI_Ialltoallv(sendbuf, sendcounts, sdispls, sendtype, recvbuf, recvcounts, rdispls, recvtype, comm->Comm, &(request->Request)));
1059
+ return rb_request;
1060
+ }
1061
+ static VALUE
570
1062
  rb_comm_reduce(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op, VALUE rb_root)
571
1063
  {
572
1064
  void *sendbuf, *recvbuf = NULL;
@@ -583,15 +1075,248 @@ rb_comm_reduce(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op, VALU
583
1075
  if (rank == root) {
584
1076
  OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
585
1077
  if (recvcount != sendcount)
586
- rb_raise(rb_eArgError, "sendbuf and recvbuf has the same length");
1078
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same length");
587
1079
  if (recvtype != sendtype)
588
- rb_raise(rb_eArgError, "sendbuf and recvbuf has the same type");
1080
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
589
1081
  }
590
1082
  Data_Get_Struct(rb_op, struct _Op, op);
591
1083
  check_error(MPI_Reduce(sendbuf, recvbuf, sendcount, sendtype, op->Op, root, comm->Comm));
592
1084
  return Qnil;
593
1085
  }
594
1086
  static VALUE
1087
+ rb_comm_ireduce(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op, VALUE rb_root)
1088
+ {
1089
+ void *sendbuf, *recvbuf = NULL;
1090
+ int sendcount=0, recvcount = 0;
1091
+ MPI_Datatype sendtype, recvtype = 0;
1092
+ int root, rank, size;
1093
+ struct _Comm *comm;
1094
+ struct _Op *op;
1095
+ struct _Request *request;
1096
+ VALUE rb_request;
1097
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
1098
+ root = NUM2INT(rb_root);
1099
+ Data_Get_Struct(self, struct _Comm, comm);
1100
+ check_error(MPI_Comm_rank(comm->Comm, &rank));
1101
+ check_error(MPI_Comm_size(comm->Comm, &size));
1102
+ if (rank == root) {
1103
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
1104
+ if (recvcount != sendcount)
1105
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same length");
1106
+ if (recvtype != sendtype)
1107
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
1108
+ }
1109
+ Data_Get_Struct(rb_op, struct _Op, op);
1110
+ rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
1111
+ request->free = true;
1112
+ check_error(MPI_Ireduce(sendbuf, recvbuf, sendcount, sendtype, op->Op, root, comm->Comm, &(request->Request)));
1113
+ return rb_request;
1114
+ }
1115
+ static VALUE
1116
+ rb_comm_reduce_scatter(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_recvcounts, VALUE rb_op)
1117
+ {
1118
+ void *sendbuf, *recvbuf = NULL;
1119
+ int sendcount=0, bufsize = 0;
1120
+ int *recvcounts;
1121
+ MPI_Datatype sendtype, recvtype = 0;
1122
+ int rank, size;
1123
+ struct _Comm *comm;
1124
+ struct _Op *op;
1125
+ int i;
1126
+ Data_Get_Struct(self, struct _Comm, comm);
1127
+ check_error(MPI_Comm_rank(comm->Comm, &rank));
1128
+ check_error(MPI_Comm_size(comm->Comm, &size));
1129
+ if ( RARRAY_LEN(rb_recvcounts) != size )
1130
+ rb_raise(rb_eArgError, "length of recvcounts must be the same as the group size");
1131
+ recvcounts = ALLOCA_N(int, size);
1132
+ sendcount = 0;
1133
+ for (i=0; i<size; i++) {
1134
+ recvcounts[i] = NUM2INT(rb_ary_entry(rb_recvcounts,i));
1135
+ sendcount += recvcounts[i];
1136
+ }
1137
+ OBJ2C(rb_sendbuf, bufsize, sendbuf, sendtype, 0);
1138
+ if (bufsize != sendcount)
1139
+ rb_raise(rb_eArgError, "length of sendbuf and total of recvcounts must be the same");
1140
+ bufsize = 0;
1141
+ OBJ2C(rb_recvbuf, bufsize, recvbuf, recvtype, 0);
1142
+ if (bufsize != recvcounts[rank])
1143
+ rb_raise(rb_eArgError, "length of recvbuf and recvcounts[myrank] must by the same");
1144
+ if (recvtype != sendtype)
1145
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
1146
+ Data_Get_Struct(rb_op, struct _Op, op);
1147
+ check_error(MPI_Reduce_scatter(sendbuf, recvbuf, recvcounts, sendtype, op->Op, comm->Comm));
1148
+ return Qnil;
1149
+ }
1150
+ static VALUE
1151
+ rb_comm_ireduce_scatter(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_recvcounts, VALUE rb_op)
1152
+ {
1153
+ void *sendbuf, *recvbuf = NULL;
1154
+ int sendcount=0, bufsize = 0;
1155
+ int *recvcounts;
1156
+ MPI_Datatype sendtype, recvtype = 0;
1157
+ int rank, size;
1158
+ struct _Comm *comm;
1159
+ struct _Op *op;
1160
+ struct _Request *request;
1161
+ VALUE rb_request;
1162
+ int i;
1163
+ Data_Get_Struct(self, struct _Comm, comm);
1164
+ check_error(MPI_Comm_rank(comm->Comm, &rank));
1165
+ check_error(MPI_Comm_size(comm->Comm, &size));
1166
+ if ( RARRAY_LEN(rb_recvcounts) != size )
1167
+ rb_raise(rb_eArgError, "length of recvcounts must be the same as the group size");
1168
+ recvcounts = ALLOCA_N(int, size);
1169
+ sendcount = 0;
1170
+ for (i=0; i<size; i++) {
1171
+ recvcounts[i] = NUM2INT(rb_ary_entry(rb_recvcounts,i));
1172
+ sendcount += recvcounts[i];
1173
+ }
1174
+ OBJ2C(rb_sendbuf, bufsize, sendbuf, sendtype, 0);
1175
+ if (bufsize != sendcount)
1176
+ rb_raise(rb_eArgError, "length of sendbuf and total of recvcounts must be the same");
1177
+ bufsize = 0;
1178
+ OBJ2C(rb_recvbuf, bufsize, recvbuf, recvtype, 0);
1179
+ if (bufsize != recvcounts[rank])
1180
+ rb_raise(rb_eArgError, "length of recvbuf and recvcounts[myrank] must by the same");
1181
+ if (recvtype != sendtype)
1182
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
1183
+ Data_Get_Struct(rb_op, struct _Op, op);
1184
+ rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
1185
+ request->free = true;
1186
+ check_error(MPI_Ireduce_scatter(sendbuf, recvbuf, recvcounts, sendtype, op->Op, comm->Comm, &(request->Request)));
1187
+ return rb_request;
1188
+ }
1189
+ static VALUE
1190
+ rb_comm_reduce_scatter_block(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
1191
+ {
1192
+ void *sendbuf, *recvbuf = NULL;
1193
+ int sendcount=0, recvcount = 0;
1194
+ MPI_Datatype sendtype, recvtype = 0;
1195
+ int size;
1196
+ struct _Comm *comm;
1197
+ struct _Op *op;
1198
+ Data_Get_Struct(self, struct _Comm, comm);
1199
+ check_error(MPI_Comm_size(comm->Comm, &size));
1200
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
1201
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
1202
+ if (sendcount != recvcount*size)
1203
+ rb_raise(rb_eArgError, "length of sendbuf must be length of recvbuf times rank size");
1204
+ if (recvtype != sendtype)
1205
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
1206
+ Data_Get_Struct(rb_op, struct _Op, op);
1207
+ check_error(MPI_Reduce_scatter_block(sendbuf, recvbuf, recvcount, sendtype, op->Op, comm->Comm));
1208
+ return Qnil;
1209
+ }
1210
+ static VALUE
1211
+ rb_comm_ireduce_scatter_block(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
1212
+ {
1213
+ void *sendbuf, *recvbuf = NULL;
1214
+ int sendcount=0, recvcount = 0;
1215
+ MPI_Datatype sendtype, recvtype = 0;
1216
+ int size;
1217
+ struct _Comm *comm;
1218
+ struct _Op *op;
1219
+ struct _Request *request;
1220
+ VALUE rb_request;
1221
+ Data_Get_Struct(self, struct _Comm, comm);
1222
+ check_error(MPI_Comm_size(comm->Comm, &size));
1223
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
1224
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
1225
+ if (sendcount != recvcount*size)
1226
+ rb_raise(rb_eArgError, "length of sendbuf must be length of recvbuf times rank size");
1227
+ if (recvtype != sendtype)
1228
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
1229
+ Data_Get_Struct(rb_op, struct _Op, op);
1230
+ rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
1231
+ request->free = true;
1232
+ check_error(MPI_Ireduce_scatter_block(sendbuf, recvbuf, recvcount, sendtype, op->Op, comm->Comm, &(request->Request)));
1233
+ return rb_request;
1234
+ }
1235
+ static VALUE
1236
+ rb_comm_scan(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
1237
+ {
1238
+ void *sendbuf, *recvbuf = NULL;
1239
+ int sendcount=0, recvcount = 0;
1240
+ MPI_Datatype sendtype, recvtype = 0;
1241
+ struct _Comm *comm;
1242
+ struct _Op *op;
1243
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
1244
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
1245
+ if (sendcount != recvcount)
1246
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same length");
1247
+ if (recvtype != sendtype)
1248
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
1249
+ Data_Get_Struct(self, struct _Comm, comm);
1250
+ Data_Get_Struct(rb_op, struct _Op, op);
1251
+ check_error(MPI_Scan(sendbuf, recvbuf, recvcount, sendtype, op->Op, comm->Comm));
1252
+ return Qnil;
1253
+ }
1254
+ static VALUE
1255
+ rb_comm_iscan(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
1256
+ {
1257
+ void *sendbuf, *recvbuf = NULL;
1258
+ int sendcount=0, recvcount = 0;
1259
+ MPI_Datatype sendtype, recvtype = 0;
1260
+ struct _Comm *comm;
1261
+ struct _Op *op;
1262
+ struct _Request *request;
1263
+ VALUE rb_request;
1264
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
1265
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
1266
+ if (sendcount != recvcount)
1267
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same length");
1268
+ if (recvtype != sendtype)
1269
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
1270
+ Data_Get_Struct(self, struct _Comm, comm);
1271
+ Data_Get_Struct(rb_op, struct _Op, op);
1272
+ rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
1273
+ request->free = true;
1274
+ check_error(MPI_Iscan(sendbuf, recvbuf, recvcount, sendtype, op->Op, comm->Comm, &(request->Request)));
1275
+ return rb_request;
1276
+ }
1277
+ static VALUE
1278
+ rb_comm_exscan(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
1279
+ {
1280
+ void *sendbuf, *recvbuf = NULL;
1281
+ int sendcount=0, recvcount = 0;
1282
+ MPI_Datatype sendtype, recvtype = 0;
1283
+ struct _Comm *comm;
1284
+ struct _Op *op;
1285
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
1286
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
1287
+ if (sendcount != recvcount)
1288
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same length");
1289
+ if (recvtype != sendtype)
1290
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
1291
+ Data_Get_Struct(self, struct _Comm, comm);
1292
+ Data_Get_Struct(rb_op, struct _Op, op);
1293
+ check_error(MPI_Exscan(sendbuf, recvbuf, recvcount, sendtype, op->Op, comm->Comm));
1294
+ return Qnil;
1295
+ }
1296
+ static VALUE
1297
+ rb_comm_iexscan(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
1298
+ {
1299
+ void *sendbuf, *recvbuf = NULL;
1300
+ int sendcount=0, recvcount = 0;
1301
+ MPI_Datatype sendtype, recvtype = 0;
1302
+ struct _Comm *comm;
1303
+ struct _Op *op;
1304
+ struct _Request *request;
1305
+ VALUE rb_request;
1306
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
1307
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
1308
+ if (sendcount != recvcount)
1309
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same length");
1310
+ if (recvtype != sendtype)
1311
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
1312
+ Data_Get_Struct(self, struct _Comm, comm);
1313
+ Data_Get_Struct(rb_op, struct _Op, op);
1314
+ rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
1315
+ request->free = true;
1316
+ check_error(MPI_Iexscan(sendbuf, recvbuf, recvcount, sendtype, op->Op, comm->Comm, &(request->Request)));
1317
+ return rb_request;
1318
+ }
1319
+ static VALUE
595
1320
  rb_comm_allreduce(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
596
1321
  {
597
1322
  void *sendbuf, *recvbuf;
@@ -606,14 +1331,40 @@ rb_comm_allreduce(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
606
1331
  check_error(MPI_Comm_size(comm->Comm, &size));
607
1332
  OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
608
1333
  if (recvcount != sendcount)
609
- rb_raise(rb_eArgError, "sendbuf and recvbuf has the same length");
1334
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same length");
610
1335
  if (recvtype != sendtype)
611
- rb_raise(rb_eArgError, "sendbuf and recvbuf has the same type");
1336
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
612
1337
  Data_Get_Struct(rb_op, struct _Op, op);
613
1338
  check_error(MPI_Allreduce(sendbuf, recvbuf, recvcount, recvtype, op->Op, comm->Comm));
614
1339
  return Qnil;
615
1340
  }
616
1341
  static VALUE
1342
+ rb_comm_iallreduce(VALUE self, VALUE rb_sendbuf, VALUE rb_recvbuf, VALUE rb_op)
1343
+ {
1344
+ void *sendbuf, *recvbuf;
1345
+ int sendcount=0, recvcount=0;
1346
+ MPI_Datatype sendtype, recvtype;
1347
+ int rank, size;
1348
+ struct _Comm *comm;
1349
+ struct _Op *op;
1350
+ struct _Request *request;
1351
+ VALUE rb_request;
1352
+ OBJ2C(rb_sendbuf, sendcount, sendbuf, sendtype, 0);
1353
+ Data_Get_Struct(self, struct _Comm, comm);
1354
+ check_error(MPI_Comm_rank(comm->Comm, &rank));
1355
+ check_error(MPI_Comm_size(comm->Comm, &size));
1356
+ OBJ2C(rb_recvbuf, recvcount, recvbuf, recvtype, 0);
1357
+ if (recvcount != sendcount)
1358
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same length");
1359
+ if (recvtype != sendtype)
1360
+ rb_raise(rb_eArgError, "sendbuf and recvbuf must have the same type");
1361
+ Data_Get_Struct(rb_op, struct _Op, op);
1362
+ rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
1363
+ request->free = true;
1364
+ check_error(MPI_Iallreduce(sendbuf, recvbuf, recvcount, recvtype, op->Op, comm->Comm, &(request->Request)));
1365
+ return rb_request;
1366
+ }
1367
+ static VALUE
617
1368
  rb_comm_get_Errhandler(VALUE self)
618
1369
  {
619
1370
  struct _Comm *comm;
@@ -643,7 +1394,19 @@ rb_comm_barrier(VALUE self)
643
1394
  struct _Comm *comm;
644
1395
  Data_Get_Struct(self, struct _Comm, comm);
645
1396
  check_error(MPI_Barrier(comm->Comm));
646
- return self;
1397
+ return Qnil;
1398
+ }
1399
+ static VALUE
1400
+ rb_comm_ibarrier(VALUE self)
1401
+ {
1402
+ struct _Comm *comm;
1403
+ struct _Request *request;
1404
+ VALUE rb_request;
1405
+ Data_Get_Struct(self, struct _Comm, comm);
1406
+ rb_request = Data_Make_Struct(cRequest, struct _Request, NULL, Request_free, request);
1407
+ request->free = true;
1408
+ check_error(MPI_Ibarrier(comm->Comm, &(request->Request)));
1409
+ return rb_request;
647
1410
  }
648
1411
 
649
1412
  // MPI::Request
@@ -698,8 +1461,10 @@ void Init_mpi()
698
1461
  // MPI
699
1462
  mMPI = rb_define_module("MPI");
700
1463
  rb_define_module_function(mMPI, "Init", rb_m_init, -1);
701
- rb_define_module_function(mMPI, "Finalize", rb_m_finalize, -1);
1464
+ rb_define_module_function(mMPI, "Finalize", rb_m_finalize, 0);
702
1465
  rb_define_module_function(mMPI, "Abort", rb_m_abort, 2);
1466
+ rb_define_module_function(mMPI, "Wtime", rb_m_wtime, 0);
1467
+ rb_define_module_function(mMPI, "Waitall", rb_m_waitall, 1);
703
1468
  rb_define_const(mMPI, "VERSION", INT2NUM(MPI_VERSION));
704
1469
  rb_define_const(mMPI, "SUBVERSION", INT2NUM(MPI_SUBVERSION));
705
1470
  rb_define_const(mMPI, "SUCCESS", INT2NUM(MPI_SUCCESS));
@@ -710,22 +1475,50 @@ void Init_mpi()
710
1475
  // rb_define_alloc_func(cComm, rb_comm_alloc);
711
1476
  rb_define_private_method(cComm, "initialize", rb_comm_initialize, 0);
712
1477
  rb_define_method(cComm, "rank", rb_comm_rank, 0);
1478
+ rb_define_method(cComm, "Rank", rb_comm_rank, 0);
713
1479
  rb_define_method(cComm, "size", rb_comm_size, 0);
1480
+ rb_define_method(cComm, "Size", rb_comm_size, 0);
714
1481
  rb_define_method(cComm, "Send", rb_comm_send, 3);
715
1482
  rb_define_method(cComm, "Isend", rb_comm_isend, 3);
716
1483
  rb_define_method(cComm, "Recv", rb_comm_recv, -1);
717
1484
  rb_define_method(cComm, "Irecv", rb_comm_irecv, -1);
718
1485
  rb_define_method(cComm, "Gather", rb_comm_gather, 3);
1486
+ rb_define_method(cComm, "Igather", rb_comm_igather, 3);
1487
+ rb_define_method(cComm, "Gatherv", rb_comm_gatherv, 5);
1488
+ rb_define_method(cComm, "Igatherv", rb_comm_igatherv, 5);
719
1489
  rb_define_method(cComm, "Allgather", rb_comm_allgather, 2);
1490
+ rb_define_method(cComm, "Iallgather", rb_comm_iallgather, 2);
1491
+ rb_define_method(cComm, "Allgatherv", rb_comm_allgatherv, 4);
1492
+ rb_define_method(cComm, "Iallgatherv", rb_comm_iallgatherv, 4);
720
1493
  rb_define_method(cComm, "Bcast", rb_comm_bcast, 2);
1494
+ rb_define_method(cComm, "Ibcast", rb_comm_ibcast, 2);
721
1495
  rb_define_method(cComm, "Scatter", rb_comm_scatter, 3);
1496
+ rb_define_method(cComm, "Iscatter", rb_comm_iscatter, 3);
1497
+ rb_define_method(cComm, "Scatterv", rb_comm_scatterv, 5);
1498
+ rb_define_method(cComm, "Iscatterv", rb_comm_iscatterv, 5);
722
1499
  rb_define_method(cComm, "Sendrecv", rb_comm_sendrecv, 6);
723
1500
  rb_define_method(cComm, "Alltoall", rb_comm_alltoall, 2);
1501
+ rb_define_method(cComm, "Ialltoall", rb_comm_ialltoall, 2);
1502
+ rb_define_method(cComm, "Alltoallv", rb_comm_alltoallv, 6);
1503
+ rb_define_method(cComm, "Ialltoallv", rb_comm_ialltoallv, 6);
1504
+ // rb_define_method(cComm, "Alltoallw", rb_comm_alltoallw, 2);
1505
+ // rb_define_method(cComm, "Ialltoallw", rb_comm_ialltoallw, 2);
724
1506
  rb_define_method(cComm, "Reduce", rb_comm_reduce, 4);
1507
+ rb_define_method(cComm, "Ireduce", rb_comm_ireduce, 4);
1508
+ rb_define_method(cComm, "Reduce_scatter", rb_comm_reduce_scatter, 4);
1509
+ rb_define_method(cComm, "Ireduce_scatter", rb_comm_ireduce_scatter, 4);
1510
+ rb_define_method(cComm, "Reduce_scatter_block", rb_comm_reduce_scatter_block, 3);
1511
+ rb_define_method(cComm, "Ireduce_scatter_block", rb_comm_ireduce_scatter_block, 3);
1512
+ rb_define_method(cComm, "Scan", rb_comm_scan, 3);
1513
+ rb_define_method(cComm, "Iscan", rb_comm_iscan, 3);
1514
+ rb_define_method(cComm, "Exscan", rb_comm_exscan, 3);
1515
+ rb_define_method(cComm, "Iexscan", rb_comm_iexscan, 3);
725
1516
  rb_define_method(cComm, "Allreduce", rb_comm_allreduce, 3);
1517
+ rb_define_method(cComm, "Iallreduce", rb_comm_iallreduce, 3);
1518
+ rb_define_method(cComm, "Barrier", rb_comm_barrier, 0);
1519
+ rb_define_method(cComm, "Ibarrier", rb_comm_ibarrier, 0);
726
1520
  rb_define_method(cComm, "Errhandler", rb_comm_get_Errhandler, 0);
727
1521
  rb_define_method(cComm, "Errhandler=", rb_comm_set_Errhandler, 1);
728
- rb_define_method(cComm, "Barrier", rb_comm_barrier, 0);
729
1522
 
730
1523
  // MPI::Request
731
1524
  cRequest = rb_define_class_under(mMPI, "Request", rb_cObject);