Esempio n. 1
0
WebCLArguments::WebCLArguments(const std::string &inputSource, int argc, char const *argv[])
    : preprocessorArgc_(0)
    , preprocessorArgv_(NULL)
    , validatorArgc_(0)
    , validatorArgv_(NULL)
    , matcherArgv_()
    , files_()
    , builtinDeclFilename_(NULL)
    , outputs_()
{
    int inputDescriptor = -1;
    char const *inputFilename = createFullTemporaryFile(inputDescriptor, &inputSource[0], inputSource.size());
    if (!inputFilename)
        return;
    files_.push_back(TemporaryFile(-1, inputFilename));
    close(inputDescriptor);

    char const *buffer = reinterpret_cast<char const*>(kernel_endlfix_cl);
    size_t length = kernel_endlfix_cl_len;
    int headerDescriptor = -1;
    char const *headerFilename = createFullTemporaryFile(headerDescriptor, buffer, length);
    if (!headerFilename)
        return;
    files_.push_back(TemporaryFile(-1, headerFilename));
    close(headerDescriptor);

    int builtinDeclDescriptor = -1;
    builtinDeclFilename_ = createEmptyTemporaryFile(builtinDeclDescriptor);
    if (!builtinDeclFilename_)
        return;
    files_.push_back(TemporaryFile(-1, builtinDeclFilename_));
    close(builtinDeclDescriptor);

    // TODO: add -Dcl_khr_fp16 etc definitions to preprocessor options
    // based on extensions passed to clvValidate()

    char const *preprocessorInvocation[] = {
        "libclv", inputFilename, "--"
    };
    const int preprocessorInvocationSize =
        sizeof(preprocessorInvocation) / sizeof(preprocessorInvocation[0]);
    char const *preprocessorOptions[] = {
        "-E", "-x", "cl", "-fno-builtin", "-ffreestanding"
    };
    const int numPreprocessorOptions =
        sizeof(preprocessorOptions) / sizeof(preprocessorOptions[0]);

    char const *validatorInvocation[] = {
        "libclv", NULL, "--"
    };
    const int validatorInvocationSize =
        sizeof(validatorInvocation) / sizeof(validatorInvocation[0]);
    char const *validatorOptions[] = {
        "-x", "cl",
        "-include", headerFilename, // has to be early (provides utility macros)
        "-include", builtinDeclFilename_ // has to be late (uses utility macros)
    };
    const int numValidatorOptions =
        sizeof(validatorOptions) / sizeof(validatorOptions[0]);

    std::set<char const *> userDefines;
    for (int i = 0; i < argc; ++i) {
        char const *option = argv[i];
        if (!std::string(option).substr(0, 2).compare("-D"))
            userDefines.insert(option);
    }

    preprocessorArgc_ =
        preprocessorInvocationSize + userDefines.size() + numPreprocessorOptions + 1;
    validatorArgc_ =
        validatorInvocationSize + argc + numValidatorOptions + 3;

    preprocessorArgv_ = new char const *[preprocessorArgc_];
    if (!preprocessorArgv_) {
        std::cerr << "Internal error. Can't create argument list for preprocessor."
                  << std::endl;
        return;
    }
    validatorArgv_ = new char const *[validatorArgc_];
    if (!validatorArgv_) {
        std::cerr << "Internal error. Can't create argument list for validator."
                  << std::endl;
        return;
    }

    // preprocessor arguments
    std::copy(preprocessorInvocation,
              preprocessorInvocation + preprocessorInvocationSize,
              preprocessorArgv_);
    std::copy(userDefines.begin(),
              userDefines.end(),
              preprocessorArgv_ + preprocessorInvocationSize);
    std::copy(preprocessorOptions,
              preprocessorOptions + numPreprocessorOptions,
              preprocessorArgv_ + preprocessorInvocationSize + userDefines.size());
    preprocessorArgv_[preprocessorArgc_ - 1] = "-ferror-limit=0";

    // validator arguments
    std::copy(validatorInvocation,
              validatorInvocation + validatorInvocationSize,
              validatorArgv_);
    std::copy(argv,
              argv + argc,
              validatorArgv_ + validatorInvocationSize);
    std::copy(validatorOptions,
              validatorOptions + numValidatorOptions,
              validatorArgv_ + validatorInvocationSize + argc);
    validatorArgv_[validatorArgc_ - 1] = "-ferror-limit=0";
    validatorArgv_[validatorArgc_ - 2] = "-fno-builtin";
    validatorArgv_[validatorArgc_ - 3] = "-ffreestanding";
}
WebCLArguments::WebCLArguments(int argc, char const *argv[])
    : preprocessorArgc_(0)
    , preprocessorArgv_(NULL)
    , validatorArgc_(0)
    , validatorArgv_(NULL)
    , matcherArgv_()
    , files_()
    , outputs_()
{
    char const *commandName = argv[0];
    char const *inputFilename = argv[1];
    const int userOptionOffset = 2;
    const int numUserOptions = argc - userOptionOffset;
    assert((argc >= userOptionOffset) &&
           "Expected at least executable name and input file in argv.");

    char const *buffer = reinterpret_cast<char const*>(kernel_endlfix_cl);
    size_t length = kernel_endlfix_cl_len;
    int headerDescriptor = -1;
    char const *headerFilename = createFullTemporaryFile(headerDescriptor, buffer, length);
    if (!headerFilename)
        return;
    files_.push_back(TemporaryFile(-1, headerFilename));
    close(headerDescriptor);
  
    char const *preprocessorInvocation[] = {
        commandName, inputFilename, "--"
    };
    const int preprocessorInvocationSize =
        sizeof(preprocessorInvocation) / sizeof(preprocessorInvocation[0]);
    char const *preprocessorOptions[] = {
        "-E", "-x", "cl"
    };
    const int numPreprocessorOptions =
        sizeof(preprocessorOptions) / sizeof(preprocessorOptions[0]);

    char const *validatorInvocation[] = {
        commandName, NULL, "--"
    };
    const int validatorInvocationSize =
        sizeof(validatorInvocation) / sizeof(validatorInvocation[0]);
    char const *validatorOptions[] = {
        "-x", "cl",
        "-ffake-address-space-map",
        "-include", headerFilename
    };
    const int numValidatorOptions =
        sizeof(validatorOptions) / sizeof(validatorOptions[0]);

    preprocessorArgc_ = preprocessorInvocationSize + numPreprocessorOptions;
    validatorArgc_ = validatorInvocationSize + numUserOptions + numValidatorOptions;

    preprocessorArgv_ = new char const *[preprocessorArgc_];
    if (!preprocessorArgv_) {
        std::cerr << "Internal error. Can't create argument list for preprocessor."
                  << std::endl;
        return;
    }
    validatorArgv_ = new char const *[validatorArgc_];
    if (!validatorArgv_) {
        std::cerr << "Internal error. Can't create argument list for validator."
                  << std::endl;
        return;
    }

    // preprocessor arguments
    std::copy(preprocessorInvocation,
              preprocessorInvocation + preprocessorInvocationSize,
              preprocessorArgv_);
    std::copy(preprocessorOptions,
              preprocessorOptions + numPreprocessorOptions,
              preprocessorArgv_ + preprocessorInvocationSize);

    // validator arguments
    std::copy(validatorInvocation,
              validatorInvocation + validatorInvocationSize,
              validatorArgv_);
    std::copy(argv + userOptionOffset,
              argv + userOptionOffset + numUserOptions,
              validatorArgv_ + validatorInvocationSize);
    std::copy(validatorOptions,
              validatorOptions + numValidatorOptions,
              validatorArgv_ + validatorInvocationSize + numUserOptions);
}