pub struct UnsafeUserOperation { /* private fields */ }
Expand description
An unsafe user-defined operation.
Unsafe user-defined operations are created from pointers to functions that have the unsafe
signatures of user functions defined in the MPI C bindings, UnsafeUserFunction
.
The recommended way to create user-defined operations is through the safer UserOperation
type. This type can be used as a work-around in situations where the libffi
dependency is not
available.
Implementations§
Source§impl UnsafeUserOperation
impl UnsafeUserOperation
Sourcepub unsafe fn associative(function: UnsafeUserFunction) -> Self
pub unsafe fn associative(function: UnsafeUserFunction) -> Self
Define an unsafe operation using a function pointer. The operation must be associative.
This is a more readable shorthand for the new
method. Refer to new
for
more information.
§Safety
The construction of an UnsafeUserOperation
asserts that function
is safe to be called
in all reductions that this UnsafeUserOperation
is used in.
Sourcepub unsafe fn commutative(function: UnsafeUserFunction) -> Self
pub unsafe fn commutative(function: UnsafeUserFunction) -> Self
Define an unsafe operation using a function pointer. The operation must be both associative and commutative.
This is a more readable shorthand for the new
method. Refer to new
for
more information.
§Safety
The construction of an UnsafeUserOperation
asserts that function
is safe to be called
in all reductions that this UnsafeUserOperation
is used in.
Examples found in repository?
68fn main() {
69 let universe = mpi::initialize().unwrap();
70 let world = universe.world();
71 let rank = world.rank();
72 let size = world.size();
73 let root_rank = 0;
74
75 if rank == root_rank {
76 let mut sum: Rank = 0;
77 mpi::request::scope(|scope| {
78 world
79 .process_at_rank(root_rank)
80 .immediate_reduce_into_root(scope, &rank, &mut sum, SystemOperation::sum())
81 .wait();
82 });
83 assert_eq!(sum, size * (size - 1) / 2);
84 } else {
85 mpi::request::scope(|scope| {
86 world
87 .process_at_rank(root_rank)
88 .immediate_reduce_into(scope, &rank, SystemOperation::sum())
89 .wait();
90 });
91 }
92
93 let mut max: Rank = -1;
94
95 mpi::request::scope(|scope| {
96 world
97 .immediate_all_reduce_into(scope, &rank, &mut max, SystemOperation::max())
98 .wait();
99 });
100 assert_eq!(max, size - 1);
101
102 let a = (0..size).collect::<Vec<_>>();
103 let mut b: Rank = 0;
104
105 mpi::request::scope(|scope| {
106 world
107 .immediate_reduce_scatter_block_into(scope, &a[..], &mut b, SystemOperation::product())
108 .wait();
109 });
110 assert_eq!(b, rank.wrapping_pow(size as u32));
111
112 test_user_operations(universe.world());
113
114 let mut d = 0;
115 let op = unsafe { UnsafeUserOperation::commutative(unsafe_add) };
116 mpi::request::scope(|scope| {
117 world
118 .immediate_all_reduce_into(scope, &rank, &mut d, &op)
119 .wait();
120 });
121 assert_eq!(d, size * (size - 1) / 2);
122}
More examples
69fn main() {
70 let universe = mpi::initialize().unwrap();
71 let world = universe.world();
72 let rank = world.rank();
73 let size = world.size();
74 let root_rank = 0;
75
76 if rank == root_rank {
77 let mut sum: Rank = 0;
78 world
79 .process_at_rank(root_rank)
80 .reduce_into_root(&rank, &mut sum, SystemOperation::sum());
81 assert_eq!(sum, size * (size - 1) / 2);
82 } else {
83 world
84 .process_at_rank(root_rank)
85 .reduce_into(&rank, SystemOperation::sum());
86 }
87
88 let mut max: Rank = -1;
89
90 world.all_reduce_into(&rank, &mut max, SystemOperation::max());
91 assert_eq!(max, size - 1);
92
93 let a: u16 = 0b0000_1111_1111_0000;
94 let b: u16 = 0b0011_1100_0011_1100;
95
96 let mut c = b;
97 collective::reduce_local_into(&a, &mut c, SystemOperation::bitwise_and());
98 assert_eq!(c, 0b0000_1100_0011_0000);
99
100 let mut d = b;
101 collective::reduce_local_into(&a, &mut d, SystemOperation::bitwise_or());
102 assert_eq!(d, 0b0011_1111_1111_1100);
103
104 let mut e = b;
105 collective::reduce_local_into(&a, &mut e, SystemOperation::bitwise_xor());
106 assert_eq!(e, 0b0011_0011_1100_1100);
107
108 let f = (0..size).collect::<Vec<_>>();
109 let mut g: Rank = 0;
110
111 world.reduce_scatter_block_into(&f[..], &mut g, SystemOperation::product());
112 assert_eq!(g, rank.wrapping_pow(size as u32));
113
114 test_user_operations(universe.world());
115
116 let mut i = 0;
117 let op = unsafe { UnsafeUserOperation::commutative(unsafe_add) };
118 world.all_reduce_into(&(rank + 1), &mut i, &op);
119 assert_eq!(i, size * (size + 1) / 2);
120}
Sourcepub unsafe fn new(commute: bool, function: UnsafeUserFunction) -> Self
pub unsafe fn new(commute: bool, function: UnsafeUserFunction) -> Self
Creates an associative and possibly commutative unsafe operation using a function pointer.
The function receives raw *mut c_void
as invec
and inoutvec
and the number of elemnts
of those two vectors as a *mut c_int
len
. It shall set inoutvec
to the value of f(invec, inoutvec)
, where f
is a binary associative operation.
If the operation is also commutative, setting commute
to true
may yield performance
benefits.
Note: The user function is not allowed to panic.
§Standard section(s)
5.9.5
§Safety
The construction of an UnsafeUserOperation
asserts that function
is safe to be called
in all reductions that this UnsafeUserOperation
is used in.