| 149 | } |
| 150 | |
| 151 | void CPUComplexTensor::dimDecrement(size_t num) |
| 152 | { |
| 153 | if ((num > m_rank) || (m_rank == 0)) |
| 154 | { |
| 155 | QCERR("dimDecrement error"); |
| 156 | throw std::runtime_error("dimDecrement error"); |
| 157 | } |
| 158 | |
| 159 | auto size = 1ull << m_rank; |
| 160 | auto sub = m_rank - num; |
| 161 | qsize_t step = 1ull << sub; |
| 162 | m_rank = this->m_rank - 1; |
| 163 | |
| 164 | auto new_size = 1ull << m_rank; |
| 165 | auto new_tensor = (qcomplex_data_t *)calloc(new_size, sizeof(qcomplex_data_t)); |
| 166 | if (nullptr == new_tensor) |
| 167 | { |
| 168 | QCERR("calloc_fail"); |
| 169 | throw calloc_fail(); |
| 170 | } |
| 171 | |
| 172 | size_t k = 0; |
| 173 | size_t step_num = size / step; |
| 174 | int threads = get_num_threads(m_rank); |
| 175 | |
| 176 | if (step_num <= 4) |
| 177 | { |
| 178 | for (long long i = 0; i < size; i += step * 2) |
| 179 | { |
| 180 | k = i / (2 * step); |
| 181 | #pragma omp parallel for num_threads(threads) |
| 182 | for (long long j = i; j < i + step; j++) |
| 183 | { |
| 184 | new_tensor[j - k * step] = (m_tensor[j] + m_tensor[j + step]); |
| 185 | } |
| 186 | } |
| 187 | } |
| 188 | else |
| 189 | { |
| 190 | #pragma omp parallel for num_threads(threads) private(k) |
| 191 | for (long long i = 0; i < size; i += step * 2) |
| 192 | { |
| 193 | k = i / (2 * step); |
| 194 | for (long long j = i; j < i + step; j++) |
| 195 | { |
| 196 | new_tensor[j - k * step] = (m_tensor[j] + m_tensor[j + step]); |
| 197 | } |
| 198 | } |
| 199 | } |
| 200 | |
| 201 | free(m_tensor); |
| 202 | m_tensor = new_tensor; |
| 203 | } |
| 204 | |
| 205 | |
| 206 | qcomplex_data_t *CPUComplexTensor::getTensor() |
no test coverage detected