2017-10-03 16 views
2

OpenCL 프레임 워크를 사용하여 GPU 계산을 할 수있는 라이브러리가 있습니다. 슬프게도, 모든 플랫폼에서 OpenCL을 사용할 수있는 것은 아닙니다. 그러나 여전히 OpenCL 기능을 제외하고 해당 플랫폼에서 내 코드를 컴파일 할 수 있기를 원합니다.라이브러리 API를 엉망으로 만들지 않고 조건부 컴파일을 구현하는 방법은 무엇입니까?

이 질문은 항상 사용할 수없는 일부 외부 리소스를 조건부로 컴파일하려는 모든 상황에 적용되며 라이브러리 API로 엉망이라고 생각합니다.

CMake :

현재 나는 이렇게 설정 한

if(ENABLE_OPENCL) 
    add_definitions(-DENABLE_OPEN_CL) 
    find_package(OpenCL REQUIRED) 
    include_directories(${OpenCL_INCLUDE_DIR}) 
    target_link_libraries(mylibrary ${OpenCL_LIBRARY}) 
endif() 

C++

// settings.hpp, exposed to public API 
class settings 
{ 
    int general_setting_1; 
    bool general_setting_2; 
    // ... Other general settings 
#ifdef ENABLE_OPEN_CL 
    int open_cl_platform_id; 
    // ... Other settings available only when OpenCL is available 
#endif 
    // More settings, possibly also conditionally compiled on other external libraries 
}; 
// computation.cpp, internal to the library 

#ifdef ENABLE_OPEN_CL 
#include <CL/cl.hpp> 
#endif 

void do_things() 
{ 
    // ... 

#ifdef ENABLE_OPEN_CL 
    if(settings.open_cl_platform_id != -1) 
    { 
     // Call OpenCL code 
    } 
#endif 

    // ... 
} 

을 그래서 라이브러리를 컴파일 할 때, 만약 I OpenCL을 사용하고 싶습니다. cmake .. -DENABLE_OPEN_CL. 이 작동하지만, 클라이언트가 ENABLE_OPEN_CL로 컴파일 된 라이브러리를 소비하는 경우, 그렇지 않으면 포함 된 라이브러리의 헤더 파일은 클라이언트에서 사용 하나, 매우 나쁜 일이 일치하지 않는, 같은 ENABLE_OPEN_CL을 정의하는 클라이언트를 강제

우연히 있다.

이렇게하면 웜이 완전히 열릴 수 있습니다. 예를 들어 클라이언트가 그 일을 잊어 버린 경우 어떻게됩니까? 다른 식별자에 동일한 식별자 이름을 사용하면 어떨까요?

이 문제를 방지 할 수 있습니까? 그렇지 않다면 헤더 파일이 클라이언트와 라이브러리에서 일치하는지 확인하고 컴파일 오류를 일으킬 수있는 방법이 있습니까? 아니면 적어도 런타임 예외가 발생합니까? 이 시나리오에 대한 올바른 접근 방법은 무엇입니까?

+0

동적로드 및 후기 바인딩을 고려해 보셨습니까? –

+0

그리고 헤더를 ENABLE_OPEN_CL 정의에 의존하지 않을 수 있습니까? 하지만이 플래그없이 컴파일 할 때 - 당신은 ERROR_NOTIMPLEMENTED를 반환하는 어떤 API에 대해서도 빈 스텁 함수 구현을 제공합니다. 그래서 클라이언트는 아무 것도 정의 할 필요가 없습니다. 그러나 OpenCL을 지원하지 않는 라이브러리에 링크되어 있으면 모든 호출이 실패합니다. 잘 문서화 된 방식)? –

+0

또 다른 방법은 빌드 설정을 기반으로 모든 적절한 정의를 사용하여 헤더 파일 (library_config.h)을 생성하고 클라이언트가 추가 할 필요가 없도록이 헤더를 라이브러리 (배포하는 공용 h- 파일에 포함)와 함께 배포하는 것입니다 임의의 코드를 자체 코드로 정의 –

답변

2

OpenCL이 지원되지 않는 경우에도 open_cl_platform_idsettings의 구성원으로 남겨 두는 것이 가장 쉬운 방법입니다. 그런 다음 라이브러리가 컴파일되지 않은 경우 OpenCL 기능을 사용하려고하면 런타임 오류가 발생합니다.

또는 두 개의 헤더 파일 settings_no_open_cl.hppsettings_open_cl.hpp을 포함하고 사용자에게 올바른 헤더 파일을 포함시켜야합니다.

+0

내가 끝낸 것은 제안 된대로'open_cl_platform_id'를 남겼습니다. 그러나 API를 명시 적으로 남겨 두지 않은 것처럼 느껴졌습니다. 그래서 또 다른 설정'bool use_open_cl'을 추가했습니다.이 설정은 해당 기능을 사용하기위한 의도를 명시 적으로 나타내려면 true로 설정해야합니다. 'use_open_cl'이 참이지만'ENABLE_OPEN_CL'이 정의되어 있지 않으면 예외가 발생합니다. –