]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
1 | // Copyright (c) 2017 Martijn Rijkeboer <mrr@sru-systems.com> |
2 | // | |
3 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
4 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
5 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
6 | // option. This file may not be copied, modified, or distributed | |
7 | // except according to those terms. | |
8 | ||
9 | use std::fmt; | |
10 | use std::fmt::Debug; | |
11 | use std::ops::{Index, IndexMut}; | |
12 | use crate::block::Block; | |
13 | ||
14 | /// Structure representing the memory matrix. | |
15 | pub struct Memory { | |
16 | /// The number of rows. | |
17 | rows: usize, | |
18 | ||
19 | /// The number of columns. | |
20 | cols: usize, | |
21 | ||
22 | /// The flat array of blocks representing the memory matrix. | |
23 | blocks: Box<[Block]>, | |
24 | } | |
25 | ||
26 | impl Memory { | |
27 | /// Creates a new memory matrix. | |
28 | pub fn new(lanes: u32, lane_length: u32) -> Memory { | |
29 | let rows = lanes as usize; | |
30 | let cols = lane_length as usize; | |
31 | let total = rows * cols; | |
32 | let blocks = vec![Block::zero(); total].into_boxed_slice(); | |
33 | Memory { | |
34 | rows, | |
35 | cols, | |
36 | blocks, | |
37 | } | |
38 | } | |
39 | ||
40 | /// Gets the mutable lanes representation of the memory matrix. | |
41 | pub fn as_lanes_mut(&mut self) -> Vec<&mut Memory> { | |
42 | let ptr: *mut Memory = self; | |
43 | let mut vec = Vec::with_capacity(self.rows); | |
44 | for _ in 0..self.rows { | |
45 | vec.push(unsafe { &mut (*ptr) }); | |
46 | } | |
47 | vec | |
48 | } | |
49 | } | |
50 | ||
51 | impl Debug for Memory { | |
52 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
53 | write!(f, "Memory {{ rows: {}, cols: {} }}", self.rows, self.cols) | |
54 | } | |
55 | } | |
56 | ||
57 | impl Index<u32> for Memory { | |
58 | type Output = Block; | |
59 | fn index(&self, index: u32) -> &Block { | |
60 | &self.blocks[index as usize] | |
61 | } | |
62 | } | |
63 | ||
64 | impl Index<u64> for Memory { | |
65 | type Output = Block; | |
66 | fn index(&self, index: u64) -> &Block { | |
67 | &self.blocks[index as usize] | |
68 | } | |
69 | } | |
70 | ||
71 | impl Index<(u32, u32)> for Memory { | |
72 | type Output = Block; | |
73 | fn index(&self, index: (u32, u32)) -> &Block { | |
74 | let pos = ((index.0 as usize) * self.cols) + (index.1 as usize); | |
75 | &self.blocks[pos] | |
76 | } | |
77 | } | |
78 | ||
79 | impl IndexMut<u32> for Memory { | |
80 | fn index_mut(&mut self, index: u32) -> &mut Block { | |
81 | &mut self.blocks[index as usize] | |
82 | } | |
83 | } | |
84 | ||
85 | impl IndexMut<u64> for Memory { | |
86 | fn index_mut(&mut self, index: u64) -> &mut Block { | |
87 | &mut self.blocks[index as usize] | |
88 | } | |
89 | } | |
90 | ||
91 | impl IndexMut<(u32, u32)> for Memory { | |
92 | fn index_mut(&mut self, index: (u32, u32)) -> &mut Block { | |
93 | let pos = ((index.0 as usize) * self.cols) + (index.1 as usize); | |
94 | &mut self.blocks[pos] | |
95 | } | |
96 | } | |
97 | ||
98 | ||
99 | #[cfg(test)] | |
100 | mod tests { | |
101 | ||
102 | use crate::memory::Memory; | |
103 | ||
104 | #[test] | |
105 | fn new_returns_correct_instance() { | |
106 | let lanes = 4; | |
107 | let lane_length = 128; | |
108 | let memory = Memory::new(lanes, lane_length); | |
109 | assert_eq!(memory.rows, lanes as usize); | |
110 | assert_eq!(memory.cols, lane_length as usize); | |
111 | assert_eq!(memory.blocks.len(), 512); | |
112 | } | |
113 | ||
114 | #[test] | |
115 | fn as_lanes_mut_returns_correct_vec() { | |
116 | let mut memory = Memory::new(4, 128); | |
117 | let lanes = memory.as_lanes_mut(); | |
118 | assert_eq!(lanes.len(), 4); | |
119 | } | |
120 | } |