Skip to content

Commit

Permalink
Merge pull request Qiskit#4 from atilag/simd-fix-win
Browse files Browse the repository at this point in the history
Fix compilation in other compilers / platforms
  • Loading branch information
hhorii authored Jun 3, 2020
2 parents 93fe8e4 + 90141c0 commit 74a59da
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 41 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,11 @@ else() # Standalone build

# We build SIMD filed separately, because they will be reached only if the
# machine running the code has SIMD support
set(SIMD_SOURCE_FILE "${PROJECT_SOURCE_DIR}/src/simulators/statevector/qubitvector_avx2.cpp")
if(APPLE OR UNIX)
set(SIMD_SOURCE_FILE "${PROJECT_SOURCE_DIR}/src/simulators/statevector/qubitvector_avx2.cpp")
set_source_files_properties(${SIMD_SOURCE_FILE} PROPERTIES COMPILE_FLAGS "-mfma -mavx2")
elseif(MSVC)
set_source_files_properties(${SIMD_SOURCE_FILE} PROPERTIES COMPILE_FLAGS "/arch:AVX2")
endif()

set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
Expand Down
10 changes: 7 additions & 3 deletions qiskit/providers/aer/backends/wrappers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,24 @@ find_package(Pybind11 REQUIRED)
# shared library.
string(REPLACE " -static " "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")

# Controllers

if(CUDA_FOUND)
set_source_files_properties(bindings.cc PROPERTIES
CUDA_SOURCE_PROPERTY_FORMAT OBJ)
endif()

# We build SIMD filed separately, because they will be reached only if the
# machine running the code has SIMD support
set(SIMD_SOURCE_FILE "../../../../../src/simulators/statevector/qubitvector_avx2.cpp")

if(APPLE OR UNIX)
set(SIMD_SOURCE_FILE "../../../../../src/simulators/statevector/qubitvector_avx2.cpp")
set_source_files_properties(${SIMD_SOURCE_FILE} PROPERTIES COMPILE_FLAGS "-mfma -mavx2")
elseif(MSVC)
set_source_files_properties(${SIMD_SOURCE_FILE} PROPERTIES COMPILE_FLAGS "/arch:AVX2")
endif()

basic_pybind11_add_module(controller_wrappers bindings.cc ${SIMD_SOURCE_FILE})

basic_pybind11_add_module(controller_wrappers ${SIMD_SOURCE_FILE} bindings.cc)
target_include_directories(controller_wrappers PRIVATE ${AER_SIMULATOR_CPP_SRC_DIR}
PRIVATE ${AER_SIMULATOR_CPP_EXTERNAL_LIBS})
target_link_libraries(controller_wrappers ${AER_LIBRARIES})
Expand Down
3 changes: 3 additions & 0 deletions src/controllers/qasm_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@
#include "simulators/matrix_product_state/matrix_product_state.hpp"
#include "simulators/stabilizer/stabilizer_state.hpp"
#include "simulators/statevector/statevector_state.hpp"
#include "simulators/statevector/qubitvector.hpp"
#include "simulators/statevector/qubitvector_avx2.hpp"
#include "simulators/superoperator/superoperator_state.hpp"
#include "transpile/delay_measure.hpp"
#include "transpile/fusion.hpp"
#include "framework/avx2_detect.hpp"


namespace AER {
namespace Simulator {

Expand Down
1 change: 1 addition & 0 deletions src/controllers/statevector_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "controller.hpp"
#include "simulators/statevector/statevector_state.hpp"
#include "simulators/statevector/qubitvector_avx2.hpp"

namespace AER {
namespace Simulator {
Expand Down
85 changes: 54 additions & 31 deletions src/framework/avx2_detect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,51 +15,74 @@
#ifndef _aer_controller_avx2_detect_hpp_
#define _aer_controller_avx2_detect_hpp_

#ifdef _WIN64
#ifdef _MSC_VER
#include <intrin.h>
#elif defined(__GNUC__)
#include <cpuid.h>
#endif
#include <array>
#include <vector>
#include <bitset>

namespace AER {
namespace {
inline void ccpuid(int cpu_info[4], int function_id){
#ifdef _MSC_VER
__cpuid(cpu_info, function_id);
#elif defined(__GNUC__)
__cpuid(function_id,
cpu_info[0],
cpu_info[1],
cpu_info[2],
cpu_info[3]);
#else // We don't support this platform intrinsics
cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0;
#endif
}

#ifdef __GNUC__
static void get_cpuid(void* p) {
int* a = (int*) p;
__cpuid(1, a[0], a[1], a[2], a[3]);
inline void cpuidex(int cpu_info[4], int function_id, int subfunction_id){
#ifdef _MSC_VER
__cpuidex(cpu_info, function_id, subfunction_id);
#elif defined(__GNUC__)
__cpuid_count(function_id, subfunction_id, cpu_info[0], cpu_info[1], cpu_info[2], cpu_info[3]);
#else // We don't support this platform intrinsics
cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0;
#endif
}
static void get_cpuid_count(void* p) {
int* a = (int*) p;
__cpuid_count(0x00000007, 0, a[0], a[1], a[2], a[3]);
}
#endif

inline bool is_avx2_supported() {
static bool cached = false;
static bool is_supported = false;
if(cached)
return is_supported;
namespace AER {

#if defined(__GNUC__)
int info[4] = {0};
get_cpuid(info);
bool fma = (info[2] >> 12 & 1);
bool avx = (info[2] >> 28 & 1);
if (!fma || !avx){
cached = true;
inline bool is_avx2_supported(){
static bool cached = false;
static bool is_supported = false;
if(cached)
return is_supported;

std::array<int, 4> cpui;
ccpuid(cpui.data(), 0);
auto num_ids = cpui[0];
if(num_ids < 7){
cached = true;
is_supported = false;
return false;
}

std::vector<std::array<int, 4>> data;
for (int i = 0; i <= num_ids; ++i){
cpuidex(cpui.data(), i, 0);
data.push_back(cpui);
}
get_cpuid_count(info);
bool avx2 = (info[1] >> 5 & 1);
cached = true;
is_supported = avx2;
return avx2;
#else
return false;
#endif
}

std::bitset<32> f_1_ECX = data[1][2];
std::bitset<32> f_7_EBX = data[7][1];

bool is_fma_supported = (f_1_ECX[12] & 1);
bool is_avx2_supported = (f_7_EBX[5] & 1);

cached = true;
is_supported = is_fma_supported && is_avx2_supported;
return is_supported;
}
// end namespace AER
}
#endif
Expand Down
1 change: 1 addition & 0 deletions src/simulators/statevector/qubitvector_avx2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "qubitvector_avx2.hpp"
#include "qubitvector.hpp"
#include "qvintrin_avx.hpp"

using namespace QV;

Expand Down
3 changes: 1 addition & 2 deletions src/simulators/statevector/qubitvector_avx2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
#include <iostream>
#include <sstream>
#include <stdexcept>

#include "qvintrin_avx.hpp"
#include <memory>

namespace QV {

Expand Down
4 changes: 1 addition & 3 deletions src/simulators/statevector/qvintrin_avx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,6 @@ inline void reorder(QV::areg_t<N>& qregs, QV::cvector_t<FloatType>& mat) {
for(size_t i = 0; i < dim; ++i) {
size_t index = 0U;
for(size_t j = 0; j < N; ++j) {


if(i & (1U << j))
index |= masks[j];
}
Expand Down Expand Up @@ -719,7 +717,7 @@ void _apply_lambda(uint64_t data_size, const uint64_t skip, Lambda&& func, const
std::sort(qubits_sorted.begin(), qubits_sorted.end());

#pragma omp parallel for if (omp_threads > 1) num_threads(omp_threads)
for (uint64_t k = 0; k < END; k += skip) {
for (int64_t k = 0; k < END; k += skip) {
const auto inds = _indexes(qubits, qubits_sorted, k);
std::forward < Lambda > (func)(inds, params);
}
Expand Down
1 change: 0 additions & 1 deletion src/simulators/statevector/statevector_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include "framework/json.hpp"
#include "simulators/state.hpp"
#include "qubitvector.hpp"
#include "qubitvector_avx2.hpp"
#ifdef AER_THRUST_SUPPORTED
#include "qubitvector_thrust.hpp"
#endif
Expand Down

0 comments on commit 74a59da

Please sign in to comment.