<commit_before>/*
 * Copyright (C) 2017 Nagisa Sekiguchi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <poll.h>
#include <limits.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdarg.h>

#include <cstdlib>

#include <symbol.h>
#include <misc/util.hpp>
#include <misc/files.h>
#include "test_common.h"

// #############################
// ##     TempFileFactory     ##
// #############################

TempFileFactory::~TempFileFactory() {
    this->freeName();
}

static char *makeTempDir() {
    const char *tmpdir = getenv("TMPDIR");
    if(tmpdir == nullptr) {
        tmpdir = "/tmp";
    }
    char *name = nullptr;
    if(asprintf(&name, "%s/test_tmp_dirXXXXXX", tmpdir) < 0) {
        fatal("%s\n", strerror(errno));
    }
    char *dirName = mkdtemp(name);
    assert(dirName != nullptr);
    assert(dirName == name);
    return dirName;
}

void TempFileFactory::createTemp() {
    this->tmpDirName = makeTempDir();

    char *name;
    if(asprintf(&name, "%s/test_tmpXXXXXX", this->tmpDirName) < 0) {
        fatal("%s\n", strerror(errno));
    }
    int fd = mkstemp(name);
    if(fd < 0) {
        fatal("%s\n", strerror(errno));
    }
    close(fd);
    this->tmpFileName = name;
}

void TempFileFactory::deleteTemp() {
    DIR *dir = opendir(this->tmpDirName);
    if(dir == nullptr) {
        fatal("%s\n", strerror(errno));
    }

    for(dirent *entry; (entry = readdir(dir)) != nullptr;) {
        if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
            continue;
        }
        std::string fullpath = this->tmpDirName;
        fullpath += '/';
        fullpath += entry->d_name;
        const char *name = fullpath.c_str();
        if(S_ISREG(ydsh::getStMode(name))) {
            if(remove(name) < 0) {
                fatal("%s: %s\n", strerror(errno), name);
            }
        } else {
            fatal("not a regular file: %s\n", name);    //FIXME: symbolic link, etc...
        }
    }
    closedir(dir);

    if(rmdir(this->tmpDirName) < 0) {
        fatal("%s\n", strerror(errno));
    }
    this->freeName();
}

void TempFileFactory::freeName() {
    free(this->tmpFileName);
    this->tmpFileName = nullptr;
    free(this->tmpDirName);
    this->tmpDirName = nullptr;
}

// ##################
// ##     Proc     ##
// ##################

int Proc::wait() {
    if(this->pid() > -1) {
        close(this->out());
        close(this->err());

        // wait for exit
        int status = 0;
        waitpid(this->pid(), &status, 0);

        this->pid_ = -1;
        this->out_ = -1;
        this->err_ = -1;
        return status;
    }
    return 0;
}

Output Proc::readAll() {
    Output output;

    struct pollfd pollfds[2]{};
    pollfds[0].fd = this->out();
    pollfds[0].events = POLLIN;
    pollfds[1].fd = this->err();
    pollfds[1].events = POLLIN;

    while(true) {
        if(poll(pollfds, ydsh::arraySize(pollfds), -1) == -1) {
            if(errno != EINTR) {
                break;
            }
        }

        unsigned int breakCount = 0;
        for(unsigned int i = 0; i < ydsh::arraySize(pollfds); i++) {
            if(pollfds[i].revents & POLLIN) {
                char buf[64];
                int readSize = read(pollfds[i].fd, buf, ydsh::arraySize(buf));
                if(readSize > 0) {
                    (i == 0 ? output.out : output.err).append(buf, readSize);
                }
                if(readSize == -1 && (errno == EAGAIN || errno == EINTR)) {
                    continue;
                }
                if(readSize <= 0) {
                    breakCount++;
                }
            } else {
                breakCount++;
            }
        }
        if(breakCount == 2) {
            break;
        }
    }
    return output;
}

static std::string toString(const ydsh::ByteBuffer &buf, bool removeLastSpace) {
    std::string out(buf.get(), buf.size());

    if(removeLastSpace) {
        for(; !out.empty() && isSpace(out.back()); out.pop_back());
    }
    return out;
}

ProcResult Proc::waitAndGetResult(bool removeLastSpace) {
    auto output = this->readAll();
    int status = this->wait();

    if(WIFEXITED(status)) {
        status = WEXITSTATUS(status);
    } else if(WIFSIGNALED(status)) {
        status = WTERMSIG(status) + 128;
    } else {
        fatal("invalid exit status\n");
    }

    return {.status = status,
            .out = toString(output.out, removeLastSpace),
            .err = toString(output.err, removeLastSpace)};
}

// #########################
// ##     ProcBuilder     ##
// #########################

ProcBuilder& ProcBuilder::addArgs(const std::vector<std::string> &values) {
    for(auto &e : values) {
        this->args.push_back(e);
    }
    return *this;
}

Proc ProcBuilder::spawn(bool usePipe) const {
    return fork(usePipe, [&] {
        char *argv[this->args.size() + 1];
        for(unsigned int i = 0; i < this->args.size(); i++) {
            argv[i] = const_cast<char *>(this->args[i].c_str());
        }
        argv[this->args.size()] = nullptr;

        this->syncEnv();
        this->syncPWD();
        execvp(argv[0], argv);
        return -errno;
    });
}

int ProcBuilder::exec(Output *output) const {
    auto proc = this->spawn(output != nullptr);
    if(output != nullptr) {
        *output = proc.readAll();
    }
    return proc.wait();
}

static constexpr unsigned int READ_PIPE = 0;
static constexpr unsigned int WRITE_PIPE = 1;

Proc ProcBuilder::forkImpl(bool usePipe) {
    // flush standard stream due to prevent mixing io buffer
    fflush(stdout);
    fflush(stderr);
    fflush(stdin);

    // create pipe
    pid_t outpipe[2];
    pid_t errpipe[2];

    if(pipe(outpipe) < 0) {
        fatal("pipe creation failed: %s\n", strerror(errno));
    }

    if(pipe(errpipe) < 0) {
        fatal("pipe creation failed: %s\n", strerror(errno));
    }

    pid_t pid = ::fork();
    if(pid > 0) {
        close(outpipe[WRITE_PIPE]);
        close(errpipe[WRITE_PIPE]);
        if(!usePipe) {
            close(outpipe[READ_PIPE]);
            close(errpipe[READ_PIPE]);
        }

        return Proc(pid, usePipe ? outpipe[READ_PIPE] : -1, usePipe ? errpipe[READ_PIPE] : -1);
    } else if(pid == 0) {
        if(usePipe) {
            dup2(outpipe[WRITE_PIPE], STDOUT_FILENO);
            dup2(errpipe[WRITE_PIPE], STDERR_FILENO);
        }
        close(outpipe[READ_PIPE]);
        close(outpipe[WRITE_PIPE]);
        close(errpipe[READ_PIPE]);
        close(errpipe[WRITE_PIPE]);

        return Proc();
    } else {
        fatal("fork failed: %s\n", strerror(errno));
    }
}

void ProcBuilder::syncPWD() const {
    size_t size = PATH_MAX;
    char buf[size];
    const char *cwd = getcwd(buf, size);
    if(cwd == nullptr) {
        fatal("current working directory is broken!!\n");
    }
    setenv(ydsh::ENV_PWD, cwd, 1);
}

void ProcBuilder::syncEnv() const {
    for(auto &pair : this->env) {
        setenv(pair.first.c_str(), pair.second.c_str(), 1);
    }
}

std::ostream &operator<<(std::ostream &stream, const ydsh::ByteBuffer &buffer) {
    for(auto &b : buffer) {
        if(b >= 32 && b <= 126) {
            stream << (char) b;
        } else {
            stream << std::showbase << std::hex << b;
        }
    }
    return stream;
}

std::string format(const char *fmt, ...) {
    va_list arg;

    va_start(arg, fmt);
    char *str = nullptr;
    if(vasprintf(&str, fmt, arg) == -1) {
        fatal("%s\n", strerror(errno));
    }
    va_end(arg);

    std::string v = str;
    free(str);
    return v;
}<commit_msg>fix test common error message<commit_after>/*
 * Copyright (C) 2017 Nagisa Sekiguchi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <poll.h>
#include <limits.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdarg.h>

#include <cstdlib>

#include <symbol.h>
#include <misc/util.hpp>
#include <misc/files.h>
#include "test_common.h"

#define error_at(fmt, ...) fatal(fmt ": %s\n", ## __VA_ARGS__, strerror(errno))

// #############################
// ##     TempFileFactory     ##
// #############################

TempFileFactory::~TempFileFactory() {
    this->freeName();
}

static char *makeTempDir() {
    const char *tmpdir = getenv("TMPDIR");
    if(tmpdir == nullptr) {
        tmpdir = "/tmp";
    }
    char *name = nullptr;
    if(asprintf(&name, "%s/test_tmp_dirXXXXXX", tmpdir) < 0) {
        error_at("");
    }
    char *dirName = mkdtemp(name);
    assert(dirName != nullptr);
    assert(dirName == name);
    return dirName;
}

void TempFileFactory::createTemp() {
    this->tmpDirName = makeTempDir();

    char *name;
    if(asprintf(&name, "%s/test_tmpXXXXXX", this->tmpDirName) < 0) {
        error_at("");
    }
    int fd = mkstemp(name);
    if(fd < 0) {
        error_at("");
    }
    close(fd);
    this->tmpFileName = name;
}

void TempFileFactory::deleteTemp() {
    DIR *dir = opendir(this->tmpDirName);
    if(dir == nullptr) {
        error_at("");
    }

    for(dirent *entry; (entry = readdir(dir)) != nullptr;) {
        if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
            continue;
        }
        std::string fullpath = this->tmpDirName;
        fullpath += '/';
        fullpath += entry->d_name;
        const char *name = fullpath.c_str();
        if(S_ISREG(ydsh::getStMode(name))) {
            if(remove(name) < 0) {
                error_at("%s", name);
            }
        } else {
            fatal("not a regular file: %s\n", name);    //FIXME: symbolic link, etc...
        }
    }
    closedir(dir);

    if(rmdir(this->tmpDirName) < 0) {
        error_at("");
    }
    this->freeName();
}

void TempFileFactory::freeName() {
    free(this->tmpFileName);
    this->tmpFileName = nullptr;
    free(this->tmpDirName);
    this->tmpDirName = nullptr;
}

// ##################
// ##     Proc     ##
// ##################

int Proc::wait() {
    if(this->pid() > -1) {
        close(this->out());
        close(this->err());

        // wait for exit
        int status = 0;
        waitpid(this->pid(), &status, 0);

        this->pid_ = -1;
        this->out_ = -1;
        this->err_ = -1;
        return status;
    }
    return 0;
}

Output Proc::readAll() {
    Output output;

    struct pollfd pollfds[2]{};
    pollfds[0].fd = this->out();
    pollfds[0].events = POLLIN;
    pollfds[1].fd = this->err();
    pollfds[1].events = POLLIN;

    while(true) {
        if(poll(pollfds, ydsh::arraySize(pollfds), -1) == -1) {
            if(errno != EINTR) {
                break;
            }
        }

        unsigned int breakCount = 0;
        for(unsigned int i = 0; i < ydsh::arraySize(pollfds); i++) {
            if(pollfds[i].revents & POLLIN) {
                char buf[64];
                int readSize = read(pollfds[i].fd, buf, ydsh::arraySize(buf));
                if(readSize > 0) {
                    (i == 0 ? output.out : output.err).append(buf, readSize);
                }
                if(readSize == -1 && (errno == EAGAIN || errno == EINTR)) {
                    continue;
                }
                if(readSize <= 0) {
                    breakCount++;
                }
            } else {
                breakCount++;
            }
        }
        if(breakCount == 2) {
            break;
        }
    }
    return output;
}

static std::string toString(const ydsh::ByteBuffer &buf, bool removeLastSpace) {
    std::string out(buf.get(), buf.size());

    if(removeLastSpace) {
        for(; !out.empty() && isSpace(out.back()); out.pop_back());
    }
    return out;
}

ProcResult Proc::waitAndGetResult(bool removeLastSpace) {
    auto output = this->readAll();
    int status = this->wait();

    if(WIFEXITED(status)) {
        status = WEXITSTATUS(status);
    } else if(WIFSIGNALED(status)) {
        status = WTERMSIG(status) + 128;
    } else {
        fatal("invalid exit status\n");
    }

    return {.status = status,
            .out = toString(output.out, removeLastSpace),
            .err = toString(output.err, removeLastSpace)};
}

// #########################
// ##     ProcBuilder     ##
// #########################

ProcBuilder& ProcBuilder::addArgs(const std::vector<std::string> &values) {
    for(auto &e : values) {
        this->args.push_back(e);
    }
    return *this;
}

Proc ProcBuilder::spawn(bool usePipe) const {
    return fork(usePipe, [&] {
        char *argv[this->args.size() + 1];
        for(unsigned int i = 0; i < this->args.size(); i++) {
            argv[i] = const_cast<char *>(this->args[i].c_str());
        }
        argv[this->args.size()] = nullptr;

        this->syncEnv();
        this->syncPWD();
        execvp(argv[0], argv);
        return -errno;
    });
}

int ProcBuilder::exec(Output *output) const {
    auto proc = this->spawn(output != nullptr);
    if(output != nullptr) {
        *output = proc.readAll();
    }
    return proc.wait();
}

static constexpr unsigned int READ_PIPE = 0;
static constexpr unsigned int WRITE_PIPE = 1;

Proc ProcBuilder::forkImpl(bool usePipe) {
    // flush standard stream due to prevent mixing io buffer
    fflush(stdout);
    fflush(stderr);
    fflush(stdin);

    // create pipe
    pid_t outpipe[2];
    pid_t errpipe[2];

    if(pipe(outpipe) < 0) {
        error_at("pipe creation failed");
    }

    if(pipe(errpipe) < 0) {
        error_at("pipe creation failed");
    }

    pid_t pid = ::fork();
    if(pid > 0) {
        close(outpipe[WRITE_PIPE]);
        close(errpipe[WRITE_PIPE]);
        if(!usePipe) {
            close(outpipe[READ_PIPE]);
            close(errpipe[READ_PIPE]);
        }

        return Proc(pid, usePipe ? outpipe[READ_PIPE] : -1, usePipe ? errpipe[READ_PIPE] : -1);
    } else if(pid == 0) {
        if(usePipe) {
            dup2(outpipe[WRITE_PIPE], STDOUT_FILENO);
            dup2(errpipe[WRITE_PIPE], STDERR_FILENO);
        }
        close(outpipe[READ_PIPE]);
        close(outpipe[WRITE_PIPE]);
        close(errpipe[READ_PIPE]);
        close(errpipe[WRITE_PIPE]);

        return Proc();
    } else {
        error_at("fork failed");
    }
}

void ProcBuilder::syncPWD() const {
    size_t size = PATH_MAX;
    char buf[size];
    const char *cwd = getcwd(buf, size);
    if(cwd == nullptr) {
        error_at("current working directory is broken!!");
    }
    setenv(ydsh::ENV_PWD, cwd, 1);
}

void ProcBuilder::syncEnv() const {
    for(auto &pair : this->env) {
        setenv(pair.first.c_str(), pair.second.c_str(), 1);
    }
}

std::ostream &operator<<(std::ostream &stream, const ydsh::ByteBuffer &buffer) {
    for(auto &b : buffer) {
        if(b >= 32 && b <= 126) {
            stream << (char) b;
        } else {
            stream << std::showbase << std::hex << b;
        }
    }
    return stream;
}

std::string format(const char *fmt, ...) {
    va_list arg;

    va_start(arg, fmt);
    char *str = nullptr;
    if(vasprintf(&str, fmt, arg) == -1) {
        fatal("%s\n", strerror(errno));
    }
    va_end(arg);

    std::string v = str;
    free(str);
    return v;
}<|endoftext|>


<commit_before>#define BOOST_TEST_MODULE TestrocFFT
#include <iostream>
#include <vector>
#include <cstdint>
#include "hip/hip_runtime_api.h"
#include "hip/hip_vector_types.h"
#include "rocfft.h"
#include <boost/test/unit_test.hpp>
#include <iostream>

BOOST_AUTO_TEST_CASE( FFT1DSingle, * boost::unit_test::tolerance(0.0001f) )
{
  // rocFFT gpu compute
        // ========================================

        rocfft_setup();

        std::size_t N = 32 << 10;
        std::size_t Nbytes = N * sizeof(float2);

        // Create HIP device buffer
        float2 *x;
        hipMalloc(&x, Nbytes);

        // Initialize data
        std::vector<float2> cx(N);
        for (std::size_t i = 0; i < N; i++)
        {
                cx[i].x = 1;
                cx[i].y = -1;
        }

        //  Copy data to device
        hipMemcpy(x, cx.data(), Nbytes, hipMemcpyHostToDevice);

        // Create fwd rocFFT fwd
        rocfft_plan fwd = NULL;
        std::size_t length = N;
        rocfft_plan_create(&fwd,
                           rocfft_placement_inplace,
                           rocfft_transform_type_complex_forward,
                           rocfft_precision_single,
                           1, &length, 1, NULL);

        // Create bwd rocFFT bwd
        rocfft_plan bwd = NULL;
        rocfft_plan_create(&bwd,
                           rocfft_placement_inplace,
                           rocfft_transform_type_complex_inverse,
                           rocfft_precision_single,
                           1, &length, 1, NULL);

        // Execute fwd
        rocfft_execute(fwd, (void**) &x, NULL, NULL);

        // Wait for execution to finish
        hipDeviceSynchronize();

        // Destroy fwd
        rocfft_plan_destroy(fwd);

        // Execute bwd
        rocfft_execute(bwd, (void**) &x, NULL, NULL);

        // Wait for execution to finish
        hipDeviceSynchronize();

        // Destroy bwd
        rocfft_plan_destroy(bwd);

        // Copy result back to host
        std::vector<float2> y(N);
        hipMemcpy(y.data(), x, Nbytes, hipMemcpyDeviceToHost);

        // Print results
        for (std::size_t i = 0; i < N; i++)
        {
          y[i].x *= 1.f/N;
          y[i].y *= 1.f/N;

          BOOST_TEST( cx[i].x == y[i].x );
          BOOST_TEST( cx[i].y == y[i].y );
        }

        // Free device buffer
        hipFree(x);

        rocfft_cleanup();

}

<commit_msg>test_rocfft finished, runs under ROCm 1.8.192-1 with rocfft 0.8.4<commit_after>#define BOOST_TEST_MODULE TestrocFFT
#include <iostream>
#include <vector>
#include <cstdint>
#include "hip/hip_runtime_api.h"
#include "hip/hip_vector_types.h"
#include "rocfft.h"
#include <boost/test/unit_test.hpp>
#include <iostream>

BOOST_AUTO_TEST_CASE( FFT1DSmall, * boost::unit_test::tolerance(0.0001f) )
{
  // rocFFT gpu compute
        // ========================================

        rocfft_setup();

        std::size_t N = 2 << 10; //should be small enough to not need a work_buffer
        std::size_t Nbytes = N * sizeof(float2);

        // Create HIP device buffer
        float2 *x;
        hipMalloc(&x, Nbytes);
        // Initialize data
        std::vector<float2> cx(N);
        for (std::size_t i = 0; i < N; i++)
        {
                cx[i].x = 1;
                cx[i].y = -1;
        }

        //  Copy data to device
        hipMemcpy(x, cx.data(), Nbytes, hipMemcpyHostToDevice);
        // Create fwd rocFFT fwd
        rocfft_plan fwd = NULL;
        std::size_t length = N;
        rocfft_plan_create(&fwd,
                           rocfft_placement_inplace,
                           rocfft_transform_type_complex_forward,
                           rocfft_precision_single,
                           1, &length, 1, NULL);

        // Create bwd rocFFT bwd
        rocfft_plan bwd = NULL;
        rocfft_plan_create(&bwd,
                           rocfft_placement_inplace,
                           rocfft_transform_type_complex_inverse,
                           rocfft_precision_single,
                           1, &length, 1, NULL);

        // Execute fwd
        rocfft_execute(fwd, (void**) &x, NULL, NULL);

        // Wait for execution to finish
        hipDeviceSynchronize();

        // Destroy fwd
        rocfft_plan_destroy(fwd);

        // Execute bwd
        rocfft_execute(bwd, (void**) &x, NULL, NULL);

        // Wait for execution to finish
        hipDeviceSynchronize();

        // Destroy bwd
        rocfft_plan_destroy(bwd);

        // Copy result back to host
        std::vector<float2> y(N);
        hipMemcpy(y.data(), x, Nbytes, hipMemcpyDeviceToHost);

        // Print results
        for (std::size_t i = 0; i < N; i++)
        {
          y[i].x *= 1.f/N;
          y[i].y *= 1.f/N;

          BOOST_TEST( cx[i].x == y[i].x );
          BOOST_TEST( cx[i].y == y[i].y );
        }

        // Free device buffer
        hipFree(x);

        rocfft_cleanup();

}

BOOST_AUTO_TEST_CASE( FFT1D, * boost::unit_test::tolerance(0.0001f) )
{
        // rocFFT gpu compute
        // ========================================

        rocfft_setup();

        std::size_t N = 128 << 10; //needs a work_buffer
        std::size_t Nbytes = N * sizeof(float2);

        // Create HIP device buffer
        float2 *x;
        hipMalloc(&x, Nbytes);
        // Initialize data
        std::vector<float2> cx(N);
        for (std::size_t i = 0; i < N; i++)
        {
                cx[i].x = 1;
                cx[i].y = -1;
        }

        //  Copy data to device
        hipMemcpy(x, cx.data(), Nbytes, hipMemcpyHostToDevice);
        // Create fwd rocFFT fwd
        rocfft_plan fwd = NULL;
        std::size_t length = N;
        rocfft_plan_create(&fwd,
                           rocfft_placement_inplace,
                           rocfft_transform_type_complex_forward,
                           rocfft_precision_single,
                           1, &length, 1, NULL);

        // Create bwd rocFFT bwd
        rocfft_plan bwd = NULL;
        rocfft_plan_create(&bwd,
                           rocfft_placement_inplace,
                           rocfft_transform_type_complex_inverse,
                           rocfft_precision_single,
                           1, &length, 1, NULL);

        // Setup work buffer
        void *workBuffer = nullptr;
        size_t workBufferSize_fwd = 0;
        rocfft_plan_get_work_buffer_size(fwd, &workBufferSize_fwd);
        size_t workBufferSize_bwd = 0;
        rocfft_plan_get_work_buffer_size(bwd, &workBufferSize_bwd);

        BOOST_REQUIRE_EQUAL(workBufferSize_bwd,workBufferSize_fwd);

        // Setup exec info to pass work buffer to the library
        rocfft_execution_info info = nullptr;
        rocfft_execution_info_create(&info);

        if(workBufferSize_fwd > 0)
        {
                hipMalloc(&workBuffer, workBufferSize_fwd);
                rocfft_execution_info_set_work_buffer(info, workBuffer, workBufferSize_fwd);
        }

        // Execute fwd
        rocfft_execute(fwd, (void**) &x, NULL, info);

        // Wait for execution to finish
        hipDeviceSynchronize();

        // Destroy fwd
        rocfft_plan_destroy(fwd);

        // Execute bwd
        rocfft_execute(bwd, (void**) &x, NULL, info);

        // Wait for execution to finish
        hipDeviceSynchronize();

        // Destroy bwd
        rocfft_plan_destroy(bwd);

        if(workBuffer)
  	     	hipFree(workBuffer);

        rocfft_execution_info_destroy(info);

        // Copy result back to host
        std::vector<float2> y(N);
        hipMemcpy(y.data(), x, Nbytes, hipMemcpyDeviceToHost);

        // Print results
        for (std::size_t i = 0; i < N; i++)
        {
                y[i].x *= 1.f/N;
                y[i].y *= 1.f/N;

                BOOST_TEST( cx[i].x == y[i].x );
                BOOST_TEST( cx[i].y == y[i].y );
        }

        // Free device buffer
        hipFree(x);

        rocfft_cleanup();

}
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file transaction.cpp
 * @author Dmitrii Khokhlov <winsvega@mail.ru>
 * @date 2015
 * Transaaction test functions.
 */

#include "TestHelper.h"

using namespace std;
using namespace json_spirit;
using namespace dev;
using namespace dev::eth;

namespace dev {  namespace test {

void doTransactionTests(json_spirit::mValue& _v, bool _fillin)
{
	for (auto& i: _v.get_obj())
	{
		cerr << i.first << endl;
		mObject& o = i.second.get_obj();

		if (_fillin == false)
		{
			BOOST_REQUIRE(o.count("rlp") > 0);
			Transaction txFromRlp;
			try
			{
				bytes stream = importByteArray(o["rlp"].get_str());
				RLP rlp(stream);
				txFromRlp = Transaction(rlp.data(), CheckSignature::Sender);
				if (!txFromRlp.signature().isValid())
					BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") );
			}
			catch(...)
			{
				BOOST_CHECK_MESSAGE(o.count("transaction") == 0, "A transaction object should not be defined because the RLP is invalid!");
				continue;
			}

			BOOST_REQUIRE(o.count("transaction") > 0);

			mObject tObj = o["transaction"].get_obj();
			Transaction txFromFields(createRLPStreamFromTransactionFields(tObj).out(), CheckSignature::Sender);

			//Check the fields restored from RLP to original fields
			BOOST_CHECK_MESSAGE(txFromFields.data() == txFromRlp.data(), "Data in given RLP not matching the Transaction data!");
			BOOST_CHECK_MESSAGE(txFromFields.value() == txFromRlp.value(), "Value in given RLP not matching the Transaction value!");
			BOOST_CHECK_MESSAGE(txFromFields.gasPrice() == txFromRlp.gasPrice(), "GasPrice in given RLP not matching the Transaction gasPrice!");
			BOOST_CHECK_MESSAGE(txFromFields.gas() == txFromRlp.gas(),"Gas in given RLP not matching the Transaction gas!");
			BOOST_CHECK_MESSAGE(txFromFields.nonce() == txFromRlp.nonce(),"Nonce in given RLP not matching the Transaction nonce!");
			BOOST_CHECK_MESSAGE(txFromFields.receiveAddress() == txFromRlp.receiveAddress(), "Receive address in given RLP not matching the Transaction 'to' address!");
			BOOST_CHECK_MESSAGE(txFromFields.sender() == txFromRlp.sender(), "Transaction sender address in given RLP not matching the Transaction 'vrs' signature!");
			BOOST_CHECK_MESSAGE(txFromFields == txFromRlp, "However, txFromFields != txFromRlp!");
			BOOST_REQUIRE (o.count("sender") > 0);

			Address addressReaded = Address(o["sender"].get_str());
			BOOST_CHECK_MESSAGE(txFromFields.sender() == addressReaded || txFromRlp.sender() == addressReaded, "Signature address of sender does not match given sender address!");
		}
		else
		{
			BOOST_REQUIRE(o.count("transaction") > 0);
			mObject tObj = o["transaction"].get_obj();

			//Construct Rlp of the given transaction
			RLPStream rlpStream = createRLPStreamFromTransactionFields(tObj);
			o["rlp"] = "0x" + toHex(rlpStream.out());

			try
			{
				Transaction txFromFields(rlpStream.out(), CheckSignature::Sender);
				if (!txFromFields.signature().isValid())
					BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") );

				o["sender"] = toString(txFromFields.sender());
			}
			catch(...)
			{
				o.erase(o.find("transaction"));
			}
		}
	}//for
}//doTransactionTests

} }// Namespace Close

BOOST_AUTO_TEST_SUITE(TransactionTests)

BOOST_AUTO_TEST_CASE(TransactionTest)
{
	dev::test::executeTests("ttTransactionTest", "/TransactionTests", dev::test::doTransactionTests);
}

BOOST_AUTO_TEST_CASE(ttWrongRLPTransaction)
{
	dev::test::executeTests("ttWrongRLPTransaction", "/TransactionTests", dev::test::doTransactionTests);
}

BOOST_AUTO_TEST_CASE(tt10mbDataField)
{
	dev::test::executeTests("tt10mbDataField", "/TransactionTests", dev::test::doTransactionTests);
}

BOOST_AUTO_TEST_CASE(ttCreateTest)
{
	for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i)
	{
		string arg = boost::unit_test::framework::master_test_suite().argv[i];
		if (arg == "--createtest")
		{
			if (boost::unit_test::framework::master_test_suite().argc <= i + 2)
			{
				cnote << "usage: ./testeth --createtest <PathToConstructor> <PathToDestiny>\n";
				return;
			}
			try
			{
				cnote << "Populating tests...";
				json_spirit::mValue v;
				string s = asString(dev::contents(boost::unit_test::framework::master_test_suite().argv[i + 1]));
				BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + (string)boost::unit_test::framework::master_test_suite().argv[i + 1] + " is empty.");
				json_spirit::read_string(s, v);
				dev::test::doTransactionTests(v, true);
				writeFile(boost::unit_test::framework::master_test_suite().argv[i + 2], asBytes(json_spirit::write_string(v, true)));
			}
			catch (Exception const& _e)
			{
				BOOST_ERROR("Failed transaction test with Exception: " << diagnostic_information(_e));
			}
			catch (std::exception const& _e)
			{
				BOOST_ERROR("Failed transaction test with Exception: " << _e.what());
			}
		}
	}
}

BOOST_AUTO_TEST_CASE(userDefinedFileTT)
{
	dev::test::userDefinedTest("--ttTest", dev::test::doTransactionTests);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>add commandline flag for tt10MBtxTest<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file transaction.cpp
 * @author Dmitrii Khokhlov <winsvega@mail.ru>
 * @date 2015
 * Transaaction test functions.
 */

#include "TestHelper.h"

using namespace std;
using namespace json_spirit;
using namespace dev;
using namespace dev::eth;

namespace dev {  namespace test {

void doTransactionTests(json_spirit::mValue& _v, bool _fillin)
{
	for (auto& i: _v.get_obj())
	{
		cerr << i.first << endl;
		mObject& o = i.second.get_obj();

		if (_fillin == false)
		{
			BOOST_REQUIRE(o.count("rlp") > 0);
			Transaction txFromRlp;
			try
			{
				bytes stream = importByteArray(o["rlp"].get_str());
				RLP rlp(stream);
				txFromRlp = Transaction(rlp.data(), CheckSignature::Sender);
				if (!txFromRlp.signature().isValid())
					BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") );
			}
			catch(...)
			{
				BOOST_CHECK_MESSAGE(o.count("transaction") == 0, "A transaction object should not be defined because the RLP is invalid!");
				continue;
			}

			BOOST_REQUIRE(o.count("transaction") > 0);

			mObject tObj = o["transaction"].get_obj();
			Transaction txFromFields(createRLPStreamFromTransactionFields(tObj).out(), CheckSignature::Sender);

			//Check the fields restored from RLP to original fields
			BOOST_CHECK_MESSAGE(txFromFields.data() == txFromRlp.data(), "Data in given RLP not matching the Transaction data!");
			BOOST_CHECK_MESSAGE(txFromFields.value() == txFromRlp.value(), "Value in given RLP not matching the Transaction value!");
			BOOST_CHECK_MESSAGE(txFromFields.gasPrice() == txFromRlp.gasPrice(), "GasPrice in given RLP not matching the Transaction gasPrice!");
			BOOST_CHECK_MESSAGE(txFromFields.gas() == txFromRlp.gas(),"Gas in given RLP not matching the Transaction gas!");
			BOOST_CHECK_MESSAGE(txFromFields.nonce() == txFromRlp.nonce(),"Nonce in given RLP not matching the Transaction nonce!");
			BOOST_CHECK_MESSAGE(txFromFields.receiveAddress() == txFromRlp.receiveAddress(), "Receive address in given RLP not matching the Transaction 'to' address!");
			BOOST_CHECK_MESSAGE(txFromFields.sender() == txFromRlp.sender(), "Transaction sender address in given RLP not matching the Transaction 'vrs' signature!");
			BOOST_CHECK_MESSAGE(txFromFields == txFromRlp, "However, txFromFields != txFromRlp!");
			BOOST_REQUIRE (o.count("sender") > 0);

			Address addressReaded = Address(o["sender"].get_str());
			BOOST_CHECK_MESSAGE(txFromFields.sender() == addressReaded || txFromRlp.sender() == addressReaded, "Signature address of sender does not match given sender address!");
		}
		else
		{
			BOOST_REQUIRE(o.count("transaction") > 0);
			mObject tObj = o["transaction"].get_obj();

			//Construct Rlp of the given transaction
			RLPStream rlpStream = createRLPStreamFromTransactionFields(tObj);
			o["rlp"] = "0x" + toHex(rlpStream.out());

			try
			{
				Transaction txFromFields(rlpStream.out(), CheckSignature::Sender);
				if (!txFromFields.signature().isValid())
					BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") );

				o["sender"] = toString(txFromFields.sender());
			}
			catch(...)
			{
				o.erase(o.find("transaction"));
			}
		}
	}//for
}//doTransactionTests

} }// Namespace Close

BOOST_AUTO_TEST_SUITE(TransactionTests)

BOOST_AUTO_TEST_CASE(TransactionTest)
{
	dev::test::executeTests("ttTransactionTest", "/TransactionTests", dev::test::doTransactionTests);
}

BOOST_AUTO_TEST_CASE(ttWrongRLPTransaction)
{
	dev::test::executeTests("ttWrongRLPTransaction", "/TransactionTests", dev::test::doTransactionTests);
}

BOOST_AUTO_TEST_CASE(tt10mbDataField)
{
	for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i)
	{
		string arg = boost::unit_test::framework::master_test_suite().argv[i];
		if (arg == "--bigdata" || arg == "--all")
		{
			auto start = chrono::steady_clock::now();

			dev::test::executeTests("tt10mbDataField", "/TransactionTests", dev::test::doTransactionTests);

			auto end = chrono::steady_clock::now();
			auto duration(chrono::duration_cast<chrono::milliseconds>(end - start));
			cnote << "test duration: " << duration.count() << " milliseconds.\n";
		}
	}

}

BOOST_AUTO_TEST_CASE(ttCreateTest)
{
	for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i)
	{
		string arg = boost::unit_test::framework::master_test_suite().argv[i];
		if (arg == "--createtest")
		{
			if (boost::unit_test::framework::master_test_suite().argc <= i + 2)
			{
				cnote << "usage: ./testeth --createtest <PathToConstructor> <PathToDestiny>\n";
				return;
			}
			try
			{
				cnote << "Populating tests...";
				json_spirit::mValue v;
				string s = asString(dev::contents(boost::unit_test::framework::master_test_suite().argv[i + 1]));
				BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + (string)boost::unit_test::framework::master_test_suite().argv[i + 1] + " is empty.");
				json_spirit::read_string(s, v);
				dev::test::doTransactionTests(v, true);
				writeFile(boost::unit_test::framework::master_test_suite().argv[i + 2], asBytes(json_spirit::write_string(v, true)));
			}
			catch (Exception const& _e)
			{
				BOOST_ERROR("Failed transaction test with Exception: " << diagnostic_information(_e));
			}
			catch (std::exception const& _e)
			{
				BOOST_ERROR("Failed transaction test with Exception: " << _e.what());
			}
		}
	}
}

BOOST_AUTO_TEST_CASE(userDefinedFileTT)
{
	dev::test::userDefinedTest("--ttTest", dev::test::doTransactionTests);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#include "Assembler.h"
#include "Basic.h"
#include "Iterate.h"
#include <iostream>
using namespace std;

namespace snot {
	Assembler::~Assembler() {
		for (auto iter = iterate(m_SubAsms); iter; ++iter) {
			for (auto asm_iter = iterate(iter->second); asm_iter; ++asm_iter) {
				delete *asm_iter;
			}
		}
	}

	size_t Assembler::translate_offset(size_t internal_offset) const {
		size_t add = 0;
		for (auto iter = iterate(m_SubAsms); iter; ++iter) {
			if (iter->first < internal_offset && iter->second.size() > 0) {
				for (auto asm_iter = iterate(iter->second); asm_iter; ++asm_iter) {
					add += (*asm_iter)->length();
				}
			}
		}
		return internal_offset + add;
	}

	void Assembler::subasm(Assembler* m) {
		m_SubAsms[offset()].push_back(m);
	}

	void Assembler::bind(Label& label) {
		label.bind(m_Code.size());

		auto iter = m_UnboundLabelReferences.begin();
		while (iter != m_UnboundLabelReferences.end()) {
			if (*iter->label == label) {
				int offset = label.offset() - (iter->offset + 4);
				byte* _offset = reinterpret_cast<byte*>(&offset);
				for (int i = 0; i < iter->size; ++i) {
					m_Code[iter->offset + i] = _offset[i];
				}

				iter = m_UnboundLabelReferences.erase(iter);
				if (iter == m_UnboundLabelReferences.end())
					break;
			}

			if (iter != m_UnboundLabelReferences.end())
				++iter;
		}
	}

	Symbol Assembler::define_symbol(const std::string& name) {
		return snot::define_symbol(m_InternalSymbols, name, Symbol(offset()));
	}

	void Assembler::compile_to(CompiledCode& code, size_t start_offset) {
		byte* buffer = code.code();

		if (!m_UnboundLabelReferences.empty()) {
			cerr << "WARNING: Unbound label references exist!" << endl;
		}

		// Copy machine code
		for (int i = 0; i < m_Code.size(); ++i) {
			for (auto iter = iterate(m_SubAsms[i]); iter; ++iter) {
				(*iter)->compile_to(code, start_offset + i);
				i += (*iter)->length();
			}

			buffer[start_offset + i] = m_Code[i];
		}

		// Copy symbols.
		for (auto table_iter = iterate(m_InternalSymbols); table_iter; ++table_iter) {
			code.set_symbol(table_iter->first, translate_offset(table_iter->second.offset()));
		}

		// Register symbol references
		for (auto iter = iterate(m_SymbolReferences); iter; ++iter) {
			Linker::Info info(iter->symbol, translate_offset(iter->offset), iter->ref_size, iter->relative, iter->relative_offset);
			code.set_symbol_reference(*iter);
		}
	}

	CompiledCode Assembler::compile() {
		CompiledCode code(length());
		compile_to(code, 0);
		return code;
	}

	void Assembler::clear() {
		m_Code.clear();
		m_InternalSymbols.clear();
		m_UnboundLabelReferences.clear();
		m_SymbolReferences.clear();
	}
}<commit_msg>fixed subasm compilation+linking<commit_after>#include "Assembler.h"
#include "Basic.h"
#include "Iterate.h"
#include <iostream>
using namespace std;

namespace snot {
	Assembler::~Assembler() {
		for (auto iter = iterate(m_SubAsms); iter; ++iter) {
			for (auto asm_iter = iterate(iter->second); asm_iter; ++asm_iter) {
				delete *asm_iter;
			}
		}
	}

	size_t Assembler::translate_offset(size_t internal_offset) const {
		size_t add = 0;
		for (auto iter = iterate(m_SubAsms); iter; ++iter) {
			if (iter->first < internal_offset && iter->second.size() > 0) {
				for (auto asm_iter = iterate(iter->second); asm_iter; ++asm_iter) {
					add += (*asm_iter)->length();
				}
			}
		}
		return internal_offset + add;
	}

	void Assembler::subasm(Assembler* m) {
		m_SubAsms[offset()].push_back(m);
	}

	void Assembler::bind(Label& label) {
		label.bind(m_Code.size());

		auto iter = m_UnboundLabelReferences.begin();
		while (iter != m_UnboundLabelReferences.end()) {
			if (*iter->label == label) {
				int offset = label.offset() - (iter->offset + 4);
				byte* _offset = reinterpret_cast<byte*>(&offset);
				for (int i = 0; i < iter->size; ++i) {
					m_Code[iter->offset + i] = _offset[i];
				}

				iter = m_UnboundLabelReferences.erase(iter);
				if (iter == m_UnboundLabelReferences.end())
					break;
			}

			if (iter != m_UnboundLabelReferences.end())
				++iter;
		}
	}

	Symbol Assembler::define_symbol(const std::string& name) {
		return snot::define_symbol(m_InternalSymbols, name, Symbol(offset()));
	}

	void Assembler::compile_to(CompiledCode& code, size_t start_offset) {
		byte* buffer = code.code();

		if (!m_UnboundLabelReferences.empty()) {
			cerr << "WARNING: Unbound label references exist!" << endl;
		}

		int len = length();

		// Copy machine code
		int target_i = start_offset;
		for (int i = 0; i < len; ++i, ++target_i) {
			if (m_SubAsms.find(i) != m_SubAsms.end()) {
				for (auto iter = iterate(m_SubAsms[i]); iter; ++iter) {
					(*iter)->compile_to(code, target_i);
					target_i += (*iter)->length();
				}
			}
			buffer[target_i] = m_Code[i];
		}

		// Copy symbols.
		for (auto table_iter = iterate(m_InternalSymbols); table_iter; ++table_iter) {
			code.set_symbol(table_iter->first, translate_offset(table_iter->second.offset()));
		}

		// Register symbol references
		for (auto iter = iterate(m_SymbolReferences); iter; ++iter) {
			Linker::Info info(*iter);
			info.offset = translate_offset(info.offset);
			code.set_symbol_reference(info);
		}
	}

	CompiledCode Assembler::compile() {
		CompiledCode code(length());
		compile_to(code, 0);
		return code;
	}

	void Assembler::clear() {
		m_Code.clear();
		m_InternalSymbols.clear();
		m_UnboundLabelReferences.clear();
		m_SymbolReferences.clear();
	}
}<|endoftext|>


<commit_before>inline
grass_points::grass_points( const std::string in_path,
			    const std::string in_actionNames,
			    const int in_scale_factor,
			    const int in_shift,
			    const int in_scene, //only for kth
			    const int in_segment_length,
			    const int in_p
)
:path(in_path), actionNames(in_actionNames), scale_factor(in_scale_factor), shift(in_shift), total_scenes(in_scene), segment_length(in_segment_length), p(in_p)
{
  actions.load( actionNames );
}

// One Grassmann Point per Video

inline
void
grass_points::calculate_onepervideo( field<string> in_all_people, int  in_dim  )
{
  all_people = in_all_people;
  dim = in_dim;
  int n_actions = actions.n_rows;
  int n_peo =  all_people.n_rows;
  //all_people.print("people");

  field <std::string> parallel_names(n_peo*n_actions,3);
  int sc = total_scenes; //Solo estoy usando 1
  int k =0;

  for (int pe = 0; pe< n_peo; ++pe)
  {
    for (int act=0; act<n_actions; ++act)
    {

      std::stringstream load_folder;
      std::stringstream load_feat_video_i;

      load_folder << path <<"kth-features_dim" << dim <<  "/sc" << sc << "/scale" << scale_factor << "-shift"<< shift ;
      load_feat_video_i << load_folder.str() << "/" << all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";

      std::ostringstream ss1;
      std::ostringstream ss2;
      ss1 << pe;
      ss2 << act;

      parallel_names(k,0) = load_feat_video_i.str();
      parallel_names(k,1) = ss1.str();
      parallel_names(k,2) = ss2.str();
      k++;

    }
  }

  //Aca podria hacer el paparelo

  omp_set_num_threads(8); //Use only 8 processors
  #pragma omp parallel for
  for (int k = 0; k< parallel_names.n_rows; ++k)
  {
    std::string load_feat_video_i   = parallel_names(k,0);

    int pe   = atoi( parallel_names(k,1).c_str() );
    int act  = atoi( parallel_names(k,2).c_str() );

    #pragma omp critical
    cout <<  all_people (pe) << "_" << actions(act) << endl;

    one_video_one_point(load_feat_video_i, sc, pe, act );
  }

}

inline
void
grass_points::one_video_one_point( std::string load_feat_video_i, int sc, int pe, int act )
{
  //cout << load_feat_video_i << endl;
  mat mat_features_video_i;

  mat_features_video_i.load( load_feat_video_i, hdf5_binary );

  std::stringstream save_folder;
  save_folder << "./kth-grass-point-one-dim" << dim << "/sc" << sc << "/scale" << scale_factor << "-shift"<< shift ;

  mat U; vec s;   mat V;
  svd(U,s,V,mat_features_video_i);
  mat Gnp = U.cols(0,p-1);

  std::stringstream save_Gnp;
  //cout << save_folder.str() << endl;
  save_Gnp << save_folder.str() << "/grass_pt_" << all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";
  //cout << save_Gnp.str() << endl;

  #pragma omp critical
  Gnp.save( save_Gnp.str(), hdf5_binary );

}

// Several Grasmann Poits per Video
inline
void
grass_points::calculate( field<string> in_all_people, int  in_dim  )
{
  all_people = in_all_people;
  dim = in_dim;
  int n_actions = actions.n_rows;
  int n_peo =  all_people.n_rows;
  //all_people.print("people");

  field <std::string> parallel_names(n_peo*n_actions,4);
  int sc = total_scenes; //Solo estoy usando 1
  int k =0;

  for (int pe = 0; pe< n_peo; ++pe)
  {
    for (int act=0; act<n_actions; ++act)
    {

      std::stringstream load_folder;
      std::stringstream load_feat_video_i;
      std::stringstream load_labels_video_i;

      load_folder << path <<"kth-features_dim" << dim <<  "/sc" << sc << "/scale" << scale_factor << "-shift"<< shift ;
      load_feat_video_i << load_folder.str() << "/" << all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";
      load_labels_video_i << load_folder.str() << "/lab_" << all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";

      std::ostringstream ss1;
      std::ostringstream ss2;
      ss1 << pe;
      ss2 << act;

      parallel_names(k,0) = load_feat_video_i.str();
      parallel_names(k,1) = load_labels_video_i.str();
      parallel_names(k,2) = ss1.str();
      parallel_names(k,3) = ss2.str();
      k++;

    }
  }

  //Aca podria hacer el paparelo

  omp_set_num_threads(8); //Use only 8 processors
  #pragma omp parallel for
  for (int k = 0; k< parallel_names.n_rows; ++k)
  {
    std::string load_feat_video_i   = parallel_names(k,0);
    std::string load_labels_video_i = parallel_names(k,1);

    int pe   = atoi( parallel_names(k,2).c_str() );
    int act  = atoi( parallel_names(k,3).c_str() );

    #pragma omp critical
    cout <<  all_people (pe) << "_" << actions(act) << endl;

    one_video(load_feat_video_i, load_labels_video_i, sc, pe, act );
  }

}

inline
void
grass_points::one_video( std::string load_feat_video_i,	std::string load_labels_video_i, int sc, int pe, int act )
{
  //cout << load_feat_video_i << endl;
  mat mat_features_video_i;
  vec lab_video_i;

  mat_features_video_i.load( load_feat_video_i, hdf5_binary );
  lab_video_i.load( load_labels_video_i, hdf5_binary );
  int n_vec = lab_video_i.n_elem;
  int last = lab_video_i( n_vec - 1 );
  //cout << last << endl;

  int seg = 0;

  std::stringstream save_folder;
  save_folder << "./kth-grass-point-dim"<< dim << "-L" << segment_length << "/sc" << sc << "/scale" << scale_factor << "-shift"<< shift ;

  for (int l=2; l<last-segment_length; l = l+4 )
  {
    std::vector<vec> feat_seg;

    for (int j=l; j< l + segment_length; ++j)
    {
      //k++;
      //cout << " " << j;
      uvec indices = find(lab_video_i == j);
      mat feat_fr = mat_features_video_i.cols(indices);

      for (int v=0; v < feat_fr.n_cols; ++v)
      {
	vec sample = feat_fr.col(v);
	feat_seg.push_back(sample);
      }

    }
    //cout << feat_seg.size() << endl;
    if (feat_seg.size()>100) // Cuando en el segmento hay mas de 100 vectores
    {
      mat mat_feat_seg(dim,feat_seg.size());

      for (uword i = 0; i < feat_seg.size(); ++i)
      {
	mat_feat_seg.col(i) = feat_seg.at(i);

      }

      mat U; vec s;   mat V;
      svd(U,s,V,mat_feat_seg);
      mat Gnp = U.cols(0,p-1);

      std::stringstream save_Gnp;
      //cout << save_folder.str() << endl;
      save_Gnp << save_folder.str() << "/grass_pt" << seg << "_"<< all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";
      //cout << save_Gnp.str() << endl;
      #pragma omp critical
      Gnp.save( save_Gnp.str(), hdf5_binary );
      seg++;
    }
    else {
      //cout << " " << stat_seg.count();
      //getchar();

    }

  }

  std::stringstream save_seg;
  vec total_seg;
  total_seg.zeros(1);
  total_seg( 0 ) = seg;
  save_seg << save_folder.str() << "/num_seg_"<< all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".dat";
  #pragma omp critical
  {
    total_seg.save( save_seg.str(), raw_ascii );
    //cout <<  all_people (pe) << "_" << actions(act) << ". Total # of segments " << seg << endl;
  }
  //cout << "press a key " ;
  //getchar();

}

<commit_msg>Run Grassman Points<commit_after>inline
grass_points::grass_points( const std::string in_path,
			    const std::string in_actionNames,
			    const int in_scale_factor,
			    const int in_shift,
			    const int in_scene, //only for kth
			    const int in_segment_length,
			    const int in_p
)
:path(in_path), actionNames(in_actionNames), scale_factor(in_scale_factor), shift(in_shift), total_scenes(in_scene), segment_length(in_segment_length), p(in_p)
{
  actions.load( actionNames );
}

// One Grassmann Point per Video

inline
void
grass_points::calculate_onepervideo( field<string> in_all_people, int  in_dim  )
{
  all_people = in_all_people;
  dim = in_dim;
  int n_actions = actions.n_rows;
  int n_peo =  all_people.n_rows;
  //all_people.print("people");

  field <std::string> parallel_names(n_peo*n_actions,3);
  int sc = total_scenes; //Solo estoy usando 1
  int k =0;

  for (int pe = 0; pe< n_peo; ++pe)
  {
    for (int act=0; act<n_actions; ++act)
    {

      std::stringstream load_folder;
      std::stringstream load_feat_video_i;

      load_folder << path <<"kth-features_dim" << dim <<  "/sc" << sc << "/scale" << scale_factor << "-shift"<< shift ;
      load_feat_video_i << load_folder.str() << "/" << all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";

      std::ostringstream ss1;
      std::ostringstream ss2;
      ss1 << pe;
      ss2 << act;

      parallel_names(k,0) = load_feat_video_i.str();
      parallel_names(k,1) = ss1.str();
      parallel_names(k,2) = ss2.str();
      k++;

    }
  }

  //Aca podria hacer el paparelo

  //omp_set_num_threads(8); //Use only 8 processors
  #pragma omp parallel for
  for (int k = 0; k< parallel_names.n_rows; ++k)
  {
    std::string load_feat_video_i   = parallel_names(k,0);

    int pe   = atoi( parallel_names(k,1).c_str() );
    int act  = atoi( parallel_names(k,2).c_str() );

    #pragma omp critical
    cout <<  all_people (pe) << "_" << actions(act) << endl;

    one_video_one_point(load_feat_video_i, sc, pe, act );
  }

}

inline
void
grass_points::one_video_one_point( std::string load_feat_video_i, int sc, int pe, int act )
{
  //cout << load_feat_video_i << endl;
  mat mat_features_video_i;

  mat_features_video_i.load( load_feat_video_i, hdf5_binary );

  std::stringstream save_folder;
  save_folder << "./kth-grass-point-one-dim" << dim << "/sc" << sc << "/scale" << scale_factor << "-shift"<< shift ;

  mat U; vec s;   mat V;
  svd(U,s,V,mat_features_video_i);
  mat Gnp = U.cols(0,p-1);

  std::stringstream save_Gnp;
  //cout << save_folder.str() << endl;
  save_Gnp << save_folder.str() << "/grass_pt_" << all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";
  //cout << save_Gnp.str() << endl;

  #pragma omp critical
  Gnp.save( save_Gnp.str(), hdf5_binary );

}

// Several Grasmann Poits per Video
inline
void
grass_points::calculate( field<string> in_all_people, int  in_dim  )
{
  all_people = in_all_people;
  dim = in_dim;
  int n_actions = actions.n_rows;
  int n_peo =  all_people.n_rows;
  //all_people.print("people");

  field <std::string> parallel_names(n_peo*n_actions,4);
  int sc = total_scenes; //Solo estoy usando 1
  int k =0;

  for (int pe = 0; pe< n_peo; ++pe)
  {
    for (int act=0; act<n_actions; ++act)
    {

      std::stringstream load_folder;
      std::stringstream load_feat_video_i;
      std::stringstream load_labels_video_i;

      load_folder << path <<"kth-features_dim" << dim <<  "/sc" << sc << "/scale" << scale_factor << "-shift"<< shift ;
      load_feat_video_i << load_folder.str() << "/" << all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";
      load_labels_video_i << load_folder.str() << "/lab_" << all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";

      std::ostringstream ss1;
      std::ostringstream ss2;
      ss1 << pe;
      ss2 << act;

      parallel_names(k,0) = load_feat_video_i.str();
      parallel_names(k,1) = load_labels_video_i.str();
      parallel_names(k,2) = ss1.str();
      parallel_names(k,3) = ss2.str();
      k++;

    }
  }

  //Aca podria hacer el paparelo

  omp_set_num_threads(8); //Use only 8 processors
  #pragma omp parallel for
  for (int k = 0; k< parallel_names.n_rows; ++k)
  {
    std::string load_feat_video_i   = parallel_names(k,0);
    std::string load_labels_video_i = parallel_names(k,1);

    int pe   = atoi( parallel_names(k,2).c_str() );
    int act  = atoi( parallel_names(k,3).c_str() );

    #pragma omp critical
    cout <<  all_people (pe) << "_" << actions(act) << endl;

    one_video(load_feat_video_i, load_labels_video_i, sc, pe, act );
  }

}

inline
void
grass_points::one_video( std::string load_feat_video_i,	std::string load_labels_video_i, int sc, int pe, int act )
{
  //cout << load_feat_video_i << endl;
  mat mat_features_video_i;
  vec lab_video_i;

  mat_features_video_i.load( load_feat_video_i, hdf5_binary );
  lab_video_i.load( load_labels_video_i, hdf5_binary );
  int n_vec = lab_video_i.n_elem;
  int last = lab_video_i( n_vec - 1 );
  //cout << last << endl;

  int seg = 0;

  std::stringstream save_folder;
  save_folder << "./kth-grass-point-dim"<< dim << "-L" << segment_length << "/sc" << sc << "/scale" << scale_factor << "-shift"<< shift ;

  for (int l=2; l<last-segment_length; l = l+4 )
  {
    std::vector<vec> feat_seg;

    for (int j=l; j< l + segment_length; ++j)
    {
      //k++;
      //cout << " " << j;
      uvec indices = find(lab_video_i == j);
      mat feat_fr = mat_features_video_i.cols(indices);

      for (int v=0; v < feat_fr.n_cols; ++v)
      {
	vec sample = feat_fr.col(v);
	feat_seg.push_back(sample);
      }

    }
    //cout << feat_seg.size() << endl;
    if (feat_seg.size()>100) // Cuando en el segmento hay mas de 100 vectores
    {
      mat mat_feat_seg(dim,feat_seg.size());

      for (uword i = 0; i < feat_seg.size(); ++i)
      {
	mat_feat_seg.col(i) = feat_seg.at(i);

      }

      mat U; vec s;   mat V;
      svd(U,s,V,mat_feat_seg);
      mat Gnp = U.cols(0,p-1);

      std::stringstream save_Gnp;
      //cout << save_folder.str() << endl;
      save_Gnp << save_folder.str() << "/grass_pt" << seg << "_"<< all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";
      //cout << save_Gnp.str() << endl;
      #pragma omp critical
      Gnp.save( save_Gnp.str(), hdf5_binary );
      seg++;
    }
    else {
      //cout << " " << stat_seg.count();
      //getchar();

    }

  }

  std::stringstream save_seg;
  vec total_seg;
  total_seg.zeros(1);
  total_seg( 0 ) = seg;
  save_seg << save_folder.str() << "/num_seg_"<< all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".dat";
  #pragma omp critical
  {
    total_seg.save( save_seg.str(), raw_ascii );
    //cout <<  all_people (pe) << "_" << actions(act) << ". Total # of segments " << seg << endl;
  }
  //cout << "press a key " ;
  //getchar();

}

<|endoftext|>


<commit_before>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2011 Laszlo Papp <djszapi@archlinux.us>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "gamesviewitem.h"
#include "lib/models/gamesmodel.h"

GamesViewItem::GamesViewItem( QWidget* parent, Qt::WindowFlags wFlags )
    : QWidget( parent, wFlags )
    , m_preview( 0 )
    , m_gameName( 0 )
    , m_gameDescription( 0 )
    , m_playButton( 0 )
    , m_layout( 0 )
{
}

void GamesViewItem::setModelIndex( const QModelIndex& index )
{
    m_index = index;
    layoutWidgets();
    setToolTips();
}

void GamesViewItem::layoutWidgets()
{
    m_layout = new QGridLayout();

    m_preview = new KTitleWidget( this );
    m_preview->setPixmap( KIcon( "gluon_creator" ) );
    // m_preview->setAcceptHoverEvents( false );
    // m_preview->setContentsMargins( 0, 0, 0, 0 );
    // m_preview->setAcceptedMouseButtons( Qt::NoButton );
    // m_preview->setFocusPolicy( Qt::NoFocus );
    // m_preview->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::MinimumExpanding );

    m_gameName = new QLabel( this );
    m_gameName->setText( m_index.sibling( m_index.row(), GluonPlayer::GamesModel::NameColumn ).data().toString() );

    m_gameDescription = new QLabel( this );
    m_gameDescription->setText( m_index.sibling( m_index.row(), GluonPlayer::GamesModel::DescriptionColumn ).data().toString() );

    m_playButton = new KTitleWidget( this );
    m_playButton->setPixmap( KIcon( "media-playback-start" ) );
    // m_playButton->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::MinimumExpanding );
    connect( m_playButton, SIGNAL( activated() ), SLOT( playGameActivated() ) );

    m_layout->addWidget( m_preview, 0, 0, 2, 1 );
    m_layout->addWidget( m_gameName, 0, 1 );
    m_layout->addWidget( m_gameDescription, 1, 1 );
    m_layout->addWidget( m_playButton, 0, 2, 2, 1 );
    setLayout( m_layout );
}

QModelIndex GamesViewItem::modelIndex() const
{
    return m_index;
}

void GamesViewItem::playGameActivated()
{
    emit gameToPlaySelected( m_index );
}

void GamesViewItem::mousePressEvent( QMouseEvent* event )
{
    Q_UNUSED( event );
    emit gameSelected( m_index );
}
<commit_msg>KDE Extended Player: Set the focus and size policy for the gamesviewitem.<commit_after>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2011 Laszlo Papp <djszapi@archlinux.us>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "gamesviewitem.h"
#include "lib/models/gamesmodel.h"

GamesViewItem::GamesViewItem( QWidget* parent, Qt::WindowFlags wFlags )
    : QWidget( parent, wFlags )
    , m_preview( 0 )
    , m_gameName( 0 )
    , m_gameDescription( 0 )
    , m_playButton( 0 )
    , m_layout( 0 )
{
}

void GamesViewItem::setModelIndex( const QModelIndex& index )
{
    m_index = index;
    layoutWidgets();
    setToolTips();
}

void GamesViewItem::layoutWidgets()
{
    m_layout = new QGridLayout();

    m_preview = new KTitleWidget( this );
    m_preview->setPixmap( KIcon( "gluon_creator" ) );
    // m_preview->setAcceptHoverEvents( false );
    // m_preview->setContentsMargins( 0, 0, 0, 0 );
    // m_preview->setAcceptedMouseButtons( Qt::NoButton );
    m_preview->setFocusPolicy( Qt::NoFocus );
    m_preview->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::MinimumExpanding );

    m_gameName = new QLabel( this );
    m_gameName->setText( m_index.sibling( m_index.row(), GluonPlayer::GamesModel::NameColumn ).data().toString() );

    m_gameDescription = new QLabel( this );
    m_gameDescription->setText( m_index.sibling( m_index.row(), GluonPlayer::GamesModel::DescriptionColumn ).data().toString() );

    m_playButton = new KTitleWidget( this );
    m_playButton->setPixmap( KIcon( "media-playback-start" ) );
    // m_playButton->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::MinimumExpanding );
    connect( m_playButton, SIGNAL( activated() ), SLOT( playGameActivated() ) );

    m_layout->addWidget( m_preview, 0, 0, 2, 1 );
    m_layout->addWidget( m_gameName, 0, 1 );
    m_layout->addWidget( m_gameDescription, 1, 1 );
    m_layout->addWidget( m_playButton, 0, 2, 2, 1 );
    setLayout( m_layout );
}

QModelIndex GamesViewItem::modelIndex() const
{
    return m_index;
}

void GamesViewItem::playGameActivated()
{
    emit gameToPlaySelected( m_index );
}

void GamesViewItem::mousePressEvent( QMouseEvent* event )
{
    Q_UNUSED( event );
    emit gameSelected( m_index );
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "Problem1.h"

/*
https://projecteuler.net/problem=1
Multiples of 3 and 5
Problem 1
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.
*/

int Problem1::SumMultiplesOf3And5Below(int range)
{
    int sum = 0;

    if (range > 0)
    {
        for (size_t i = 1; i < range; i++)
        {
            if (i % 3 == 0 || i % 5 == 0)
            {
                sum += i;
            }
        }
    }

    return sum;
}

long Problem1::SumBelow(long range)
{
    return -1;
}
<commit_msg>green-commit - SumBelow_Input0_Returns0<commit_after>#include "stdafx.h"
#include "Problem1.h"

/*
https://projecteuler.net/problem=1
Multiples of 3 and 5
Problem 1
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.
*/

int Problem1::SumMultiplesOf3And5Below(int range)
{
    int sum = 0;

    if (range > 0)
    {
        for (size_t i = 1; i < range; i++)
        {
            if (i % 3 == 0 || i % 5 == 0)
            {
                sum += i;
            }
        }
    }

    return sum;
}

long Problem1::SumBelow(long range)
{
    return 0;
}
<|endoftext|>


<commit_before>// Generator requires C++11
#if __cplusplus > 199711L || _MSC_VER >= 1800

#include "Generator.h"

namespace {

// Return true iff the name is valid for Generators or Params.
// (NOTE: gcc didn't add proper std::regex support until v4.9;
// we don't yet require this, hence the hand-rolled replacement.)

bool is_alpha(char c) { return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); }

// Note that this includes '_'
bool is_alnum(char c) { return is_alpha(c) || (c == '_') || (c >= '0' && c <= '9'); }

// Basically, a valid C identifier, except:
//
// -- initial _ is forbidden (rather than merely "reserved")
// -- two underscores in a row is also forbidden
bool is_valid_name(const std::string& n) {
    if (n.empty()) return false;
    if (!is_alpha(n[0])) return false;
    for (size_t i = 1; i < n.size(); ++i) {
        if (!is_alnum(n[i])) return false;
        if (n[i] == '_' && n[i-1] == '_') return false;
    }
    return true;
}

}  // namespace

namespace Halide {
namespace Internal {

const std::map<std::string, Halide::Type> halide_type_enum_map{
    {"int8", Halide::Int(8)},
    {"int16", Halide::Int(16)},
    {"int32", Halide::Int(32)},
    {"uint8", Halide::UInt(8)},
    {"uint16", Halide::UInt(16)},
    {"uint32", Halide::UInt(32)},
    {"float32", Halide::Float(32)},
    {"float64", Halide::Float(64)}
};

int generate_filter_main(int argc, char **argv, std::ostream &cerr) {
    const char kUsage[] = "gengen [-g GENERATOR_NAME] [-f FUNCTION_NAME] [-o OUTPUT_DIR]  "
                          "target=target-string [generator_arg=value [...]]\n";

    std::map<std::string, std::string> flags_info = { { "-f", "" }, { "-g", "" }, { "-o", "" } };
    std::map<std::string, std::string> generator_args;

    for (int i = 1; i < argc; ++i) {
        if (argv[i][0] != '-') {
            std::vector<std::string> v = split_string(argv[i], "=");
            if (v.size() != 2 || v[0].empty() || v[1].empty()) {
                cerr << kUsage;
                return 1;
            }
            generator_args[v[0]] = v[1];
            continue;
        }
        auto it = flags_info.find(argv[i]);
        if (it != flags_info.end()) {
            if (i + 1 >= argc) {
                cerr << kUsage;
                return 1;
            }
            it->second = argv[i + 1];
            ++i;
            continue;
        }
        cerr << "Unknown flag: " << argv[i] << "\n";
        cerr << kUsage;
        return 1;
    }

    std::vector<std::string> generator_names = GeneratorRegistry::enumerate();
    if (generator_names.size() == 0) {
        cerr << "No generators have been registered\n";
        cerr << kUsage;
        return 1;
    }

    std::string generator_name = flags_info["-g"];
    if (generator_name.empty()) {
        // If -g isn't specified, but there's only one generator registered, just use that one.
        if (generator_names.size() != 1) {
            cerr << "-g must be specified if multiple generators are registered:\n";
            for (auto name : generator_names) {
                cerr << "    " << name << "\n";
            }
            cerr << kUsage;
            return 1;
        }
        generator_name = generator_names[0];
    }
    std::string function_name = flags_info["-f"];
    if (function_name.empty()) {
        // If -f isn't specified, assume function name = generator name.
        function_name = generator_name;
    }
    std::string output_dir = flags_info["-o"];
    if (output_dir.empty()) {
        cerr << "-o must always be specified.\n";
        cerr << kUsage;
        return 1;
    }
    if (generator_args.find("target") == generator_args.end()) {
        cerr << "Target missing\n";
        cerr << kUsage;
        return 1;
    }

    std::unique_ptr<GeneratorBase> gen = GeneratorRegistry::create(generator_name, generator_args);
    if (gen == nullptr) {
        cerr << "Unknown generator: " << generator_name << "\n";
        cerr << kUsage;
        return 1;
    }
    gen->emit_filter(output_dir, function_name);
    return 0;
}

GeneratorParamBase::GeneratorParamBase(const std::string &name) : name(name) {
    ObjectInstanceRegistry::register_instance(this, 0, ObjectInstanceRegistry::GeneratorParam,
                                              this);
}

GeneratorParamBase::~GeneratorParamBase() { ObjectInstanceRegistry::unregister_instance(this); }

/* static */
GeneratorRegistry &GeneratorRegistry::get_registry() {
    static GeneratorRegistry *registry = new GeneratorRegistry;
    return *registry;
}

/* static */
void GeneratorRegistry::register_factory(const std::string &name,
                                         std::unique_ptr<GeneratorFactory> factory) {
    user_assert(is_valid_name(name)) << "Invalid Generator name: " << name;
    GeneratorRegistry &registry = get_registry();
    std::lock_guard<std::mutex> lock(registry.mutex);
    internal_assert(registry.factories.find(name) == registry.factories.end())
        << "Duplicate Generator name: " << name;
    registry.factories[name] = std::move(factory);
}

/* static */
void GeneratorRegistry::unregister_factory(const std::string &name) {
    GeneratorRegistry &registry = get_registry();
    std::lock_guard<std::mutex> lock(registry.mutex);
    internal_assert(registry.factories.find(name) != registry.factories.end())
        << "Generator not found: " << name;
    registry.factories.erase(name);
}

/* static */
std::unique_ptr<GeneratorBase> GeneratorRegistry::create(const std::string &name,
                                                         const GeneratorParamValues &params) {
    GeneratorRegistry &registry = get_registry();
    std::lock_guard<std::mutex> lock(registry.mutex);
    auto it = registry.factories.find(name);
    user_assert(it != registry.factories.end()) << "Generator not found: " << name;
    return it->second->create(params);
}

/* static */
std::vector<std::string> GeneratorRegistry::enumerate() {
    GeneratorRegistry &registry = get_registry();
    std::lock_guard<std::mutex> lock(registry.mutex);
    std::vector<std::string> result;
    for (auto it = registry.factories.begin(); it != registry.factories.end(); ++it) {
        result.push_back(it->first);
    }
    return result;
}

GeneratorBase::GeneratorBase(size_t size) : size(size), params_built(false) {
    ObjectInstanceRegistry::register_instance(this, size, ObjectInstanceRegistry::Generator, this);
}

GeneratorBase::~GeneratorBase() { ObjectInstanceRegistry::unregister_instance(this); }

void GeneratorBase::build_params() {
    if (!params_built) {
        std::vector<void *> vf = ObjectInstanceRegistry::instances_in_range(
            this, size, ObjectInstanceRegistry::FilterParam);
        for (size_t i = 0; i < vf.size(); ++i) {
            Parameter *param = static_cast<Parameter *>(vf[i]);
            internal_assert(param != nullptr);
            // Param<void*> is not allowed, regardless of name.
            user_assert(!param->type().is_handle()) << "Param<void*> is not allowed in a Generator.";
            user_assert(param->is_explicit_name()) << "Params in Generators must have explicit names: " << param->name();
            user_assert(is_valid_name(param->name())) << "Invalid Param name: " << param->name();
            user_assert(filter_params.find(param->name()) == filter_params.end())
                << "Duplicate Param name: " << param->name();
            filter_params[param->name()] = param;
            filter_arguments.push_back(Argument(param->name(), param->is_buffer(), param->type()));
        }

        std::vector<void *> vg = ObjectInstanceRegistry::instances_in_range(
            this, size, ObjectInstanceRegistry::GeneratorParam);
        for (size_t i = 0; i < vg.size(); ++i) {
            GeneratorParamBase *param = static_cast<GeneratorParamBase *>(vg[i]);
            internal_assert(param != nullptr);
            user_assert(is_valid_name(param->name)) << "Invalid GeneratorParam name: " << param->name;
            user_assert(generator_params.find(param->name) == generator_params.end())
                << "Duplicate GeneratorParam name: " << param->name;
            generator_params[param->name] = param;
        }
        params_built = true;
    }
}

GeneratorParamValues GeneratorBase::get_generator_param_values() {
    build_params();
    GeneratorParamValues results;
    for (auto key_value : generator_params) {
        GeneratorParamBase *param = key_value.second;
        results[param->name] = param->to_string();
    }
    return results;
}

void GeneratorBase::set_generator_param_values(const GeneratorParamValues &params) {
    build_params();
    for (auto key_value : params) {
        const std::string &key = key_value.first;
        const std::string &value = key_value.second;
        auto param = generator_params.find(key);
        user_assert(param != generator_params.end())
            << "Generator has no GeneratorParam named: " << key;
        param->second->from_string(value);
    }
}

void GeneratorBase::emit_filter(const std::string &output_dir,
                                const std::string &function_name,
                                const std::string &file_base_name,
                                const EmitOptions &options) {
    build_params();

    Func func = build();

    std::vector<Halide::Argument> inputs = get_filter_arguments();
    std::string base_path = output_dir + "/" + (file_base_name.empty() ? function_name : file_base_name);
    if (options.emit_o) {
        func.compile_to_object(base_path + ".o", inputs, function_name, target);
    }
    if (options.emit_h) {
        func.compile_to_header(base_path + ".h", inputs, function_name, target);
    }
    if (options.emit_cpp) {
        func.compile_to_c(base_path + ".cpp", inputs, function_name, target);
    }
    if (options.emit_assembly) {
        func.compile_to_assembly(base_path + ".s", inputs, function_name, target);
    }
    if (options.emit_bitcode) {
        func.compile_to_bitcode(base_path + ".bc", inputs, function_name, target);
    }
    if (options.emit_stmt) {
        func.compile_to_lowered_stmt(base_path + ".stmt", Halide::Text, target);
    }
    if (options.emit_stmt_html) {
        func.compile_to_lowered_stmt(base_path + ".html", Halide::HTML, target);
    }
}

Func GeneratorBase::call_extern(std::initializer_list<ExternFuncArgument> function_arguments,
                                 std::string function_name){
    Func f = build();
    Func f_extern;
    if (function_name.empty()) {
        function_name = generator_name();
        user_assert(!function_name.empty()) << "call_extern: generator_name is empty";
    }
    f_extern.define_extern(function_name, function_arguments, f.output_types(), f.dimensions());
    return f_extern;
}

Func GeneratorBase::call_extern_by_name(const std::string &generator_name,
                                        std::initializer_list<ExternFuncArgument> function_arguments,
                                        const std::string &function_name,
                                        const GeneratorParamValues &generator_params) {
    std::unique_ptr<GeneratorBase> extern_gen = GeneratorRegistry::create(generator_name, generator_params);
    user_assert(extern_gen != nullptr) << "Unknown generator: " << generator_name << "\n";
    // Note that the Generator's target is not set; at present, this shouldn't matter for
    // define_extern() functions, since none of the linkage should vary by Target.
    return extern_gen->call_extern(function_arguments, function_name);
}

}  // namespace Internal
}  // namespace Halide

#endif  // __cplusplus > 199711L
<commit_msg>Generators should allow Param<void*><commit_after>// Generator requires C++11
#if __cplusplus > 199711L || _MSC_VER >= 1800

#include "Generator.h"

namespace {

// Return true iff the name is valid for Generators or Params.
// (NOTE: gcc didn't add proper std::regex support until v4.9;
// we don't yet require this, hence the hand-rolled replacement.)

bool is_alpha(char c) { return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); }

// Note that this includes '_'
bool is_alnum(char c) { return is_alpha(c) || (c == '_') || (c >= '0' && c <= '9'); }

// Basically, a valid C identifier, except:
//
// -- initial _ is forbidden (rather than merely "reserved")
// -- two underscores in a row is also forbidden
bool is_valid_name(const std::string& n) {
    if (n.empty()) return false;
    if (!is_alpha(n[0])) return false;
    for (size_t i = 1; i < n.size(); ++i) {
        if (!is_alnum(n[i])) return false;
        if (n[i] == '_' && n[i-1] == '_') return false;
    }
    return true;
}

}  // namespace

namespace Halide {
namespace Internal {

const std::map<std::string, Halide::Type> halide_type_enum_map{
    {"int8", Halide::Int(8)},
    {"int16", Halide::Int(16)},
    {"int32", Halide::Int(32)},
    {"uint8", Halide::UInt(8)},
    {"uint16", Halide::UInt(16)},
    {"uint32", Halide::UInt(32)},
    {"float32", Halide::Float(32)},
    {"float64", Halide::Float(64)}
};

int generate_filter_main(int argc, char **argv, std::ostream &cerr) {
    const char kUsage[] = "gengen [-g GENERATOR_NAME] [-f FUNCTION_NAME] [-o OUTPUT_DIR]  "
                          "target=target-string [generator_arg=value [...]]\n";

    std::map<std::string, std::string> flags_info = { { "-f", "" }, { "-g", "" }, { "-o", "" } };
    std::map<std::string, std::string> generator_args;

    for (int i = 1; i < argc; ++i) {
        if (argv[i][0] != '-') {
            std::vector<std::string> v = split_string(argv[i], "=");
            if (v.size() != 2 || v[0].empty() || v[1].empty()) {
                cerr << kUsage;
                return 1;
            }
            generator_args[v[0]] = v[1];
            continue;
        }
        auto it = flags_info.find(argv[i]);
        if (it != flags_info.end()) {
            if (i + 1 >= argc) {
                cerr << kUsage;
                return 1;
            }
            it->second = argv[i + 1];
            ++i;
            continue;
        }
        cerr << "Unknown flag: " << argv[i] << "\n";
        cerr << kUsage;
        return 1;
    }

    std::vector<std::string> generator_names = GeneratorRegistry::enumerate();
    if (generator_names.size() == 0) {
        cerr << "No generators have been registered\n";
        cerr << kUsage;
        return 1;
    }

    std::string generator_name = flags_info["-g"];
    if (generator_name.empty()) {
        // If -g isn't specified, but there's only one generator registered, just use that one.
        if (generator_names.size() != 1) {
            cerr << "-g must be specified if multiple generators are registered:\n";
            for (auto name : generator_names) {
                cerr << "    " << name << "\n";
            }
            cerr << kUsage;
            return 1;
        }
        generator_name = generator_names[0];
    }
    std::string function_name = flags_info["-f"];
    if (function_name.empty()) {
        // If -f isn't specified, assume function name = generator name.
        function_name = generator_name;
    }
    std::string output_dir = flags_info["-o"];
    if (output_dir.empty()) {
        cerr << "-o must always be specified.\n";
        cerr << kUsage;
        return 1;
    }
    if (generator_args.find("target") == generator_args.end()) {
        cerr << "Target missing\n";
        cerr << kUsage;
        return 1;
    }

    std::unique_ptr<GeneratorBase> gen = GeneratorRegistry::create(generator_name, generator_args);
    if (gen == nullptr) {
        cerr << "Unknown generator: " << generator_name << "\n";
        cerr << kUsage;
        return 1;
    }
    gen->emit_filter(output_dir, function_name);
    return 0;
}

GeneratorParamBase::GeneratorParamBase(const std::string &name) : name(name) {
    ObjectInstanceRegistry::register_instance(this, 0, ObjectInstanceRegistry::GeneratorParam,
                                              this);
}

GeneratorParamBase::~GeneratorParamBase() { ObjectInstanceRegistry::unregister_instance(this); }

/* static */
GeneratorRegistry &GeneratorRegistry::get_registry() {
    static GeneratorRegistry *registry = new GeneratorRegistry;
    return *registry;
}

/* static */
void GeneratorRegistry::register_factory(const std::string &name,
                                         std::unique_ptr<GeneratorFactory> factory) {
    user_assert(is_valid_name(name)) << "Invalid Generator name: " << name;
    GeneratorRegistry &registry = get_registry();
    std::lock_guard<std::mutex> lock(registry.mutex);
    internal_assert(registry.factories.find(name) == registry.factories.end())
        << "Duplicate Generator name: " << name;
    registry.factories[name] = std::move(factory);
}

/* static */
void GeneratorRegistry::unregister_factory(const std::string &name) {
    GeneratorRegistry &registry = get_registry();
    std::lock_guard<std::mutex> lock(registry.mutex);
    internal_assert(registry.factories.find(name) != registry.factories.end())
        << "Generator not found: " << name;
    registry.factories.erase(name);
}

/* static */
std::unique_ptr<GeneratorBase> GeneratorRegistry::create(const std::string &name,
                                                         const GeneratorParamValues &params) {
    GeneratorRegistry &registry = get_registry();
    std::lock_guard<std::mutex> lock(registry.mutex);
    auto it = registry.factories.find(name);
    user_assert(it != registry.factories.end()) << "Generator not found: " << name;
    return it->second->create(params);
}

/* static */
std::vector<std::string> GeneratorRegistry::enumerate() {
    GeneratorRegistry &registry = get_registry();
    std::lock_guard<std::mutex> lock(registry.mutex);
    std::vector<std::string> result;
    for (auto it = registry.factories.begin(); it != registry.factories.end(); ++it) {
        result.push_back(it->first);
    }
    return result;
}

GeneratorBase::GeneratorBase(size_t size) : size(size), params_built(false) {
    ObjectInstanceRegistry::register_instance(this, size, ObjectInstanceRegistry::Generator, this);
}

GeneratorBase::~GeneratorBase() { ObjectInstanceRegistry::unregister_instance(this); }

void GeneratorBase::build_params() {
    if (!params_built) {
        std::vector<void *> vf = ObjectInstanceRegistry::instances_in_range(
            this, size, ObjectInstanceRegistry::FilterParam);
        for (size_t i = 0; i < vf.size(); ++i) {
            Parameter *param = static_cast<Parameter *>(vf[i]);
            internal_assert(param != nullptr);
            user_assert(param->is_explicit_name()) << "Params in Generators must have explicit names: " << param->name();
            user_assert(is_valid_name(param->name())) << "Invalid Param name: " << param->name();
            user_assert(filter_params.find(param->name()) == filter_params.end())
                << "Duplicate Param name: " << param->name();
            filter_params[param->name()] = param;
            filter_arguments.push_back(Argument(param->name(), param->is_buffer(), param->type()));
        }

        std::vector<void *> vg = ObjectInstanceRegistry::instances_in_range(
            this, size, ObjectInstanceRegistry::GeneratorParam);
        for (size_t i = 0; i < vg.size(); ++i) {
            GeneratorParamBase *param = static_cast<GeneratorParamBase *>(vg[i]);
            internal_assert(param != nullptr);
            user_assert(is_valid_name(param->name)) << "Invalid GeneratorParam name: " << param->name;
            user_assert(generator_params.find(param->name) == generator_params.end())
                << "Duplicate GeneratorParam name: " << param->name;
            generator_params[param->name] = param;
        }
        params_built = true;
    }
}

GeneratorParamValues GeneratorBase::get_generator_param_values() {
    build_params();
    GeneratorParamValues results;
    for (auto key_value : generator_params) {
        GeneratorParamBase *param = key_value.second;
        results[param->name] = param->to_string();
    }
    return results;
}

void GeneratorBase::set_generator_param_values(const GeneratorParamValues &params) {
    build_params();
    for (auto key_value : params) {
        const std::string &key = key_value.first;
        const std::string &value = key_value.second;
        auto param = generator_params.find(key);
        user_assert(param != generator_params.end())
            << "Generator has no GeneratorParam named: " << key;
        param->second->from_string(value);
    }
}

void GeneratorBase::emit_filter(const std::string &output_dir,
                                const std::string &function_name,
                                const std::string &file_base_name,
                                const EmitOptions &options) {
    build_params();

    Func func = build();

    std::vector<Halide::Argument> inputs = get_filter_arguments();
    std::string base_path = output_dir + "/" + (file_base_name.empty() ? function_name : file_base_name);
    if (options.emit_o) {
        func.compile_to_object(base_path + ".o", inputs, function_name, target);
    }
    if (options.emit_h) {
        func.compile_to_header(base_path + ".h", inputs, function_name, target);
    }
    if (options.emit_cpp) {
        func.compile_to_c(base_path + ".cpp", inputs, function_name, target);
    }
    if (options.emit_assembly) {
        func.compile_to_assembly(base_path + ".s", inputs, function_name, target);
    }
    if (options.emit_bitcode) {
        func.compile_to_bitcode(base_path + ".bc", inputs, function_name, target);
    }
    if (options.emit_stmt) {
        func.compile_to_lowered_stmt(base_path + ".stmt", Halide::Text, target);
    }
    if (options.emit_stmt_html) {
        func.compile_to_lowered_stmt(base_path + ".html", Halide::HTML, target);
    }
}

Func GeneratorBase::call_extern(std::initializer_list<ExternFuncArgument> function_arguments,
                                 std::string function_name){
    Func f = build();
    Func f_extern;
    if (function_name.empty()) {
        function_name = generator_name();
        user_assert(!function_name.empty()) << "call_extern: generator_name is empty";
    }
    f_extern.define_extern(function_name, function_arguments, f.output_types(), f.dimensions());
    return f_extern;
}

Func GeneratorBase::call_extern_by_name(const std::string &generator_name,
                                        std::initializer_list<ExternFuncArgument> function_arguments,
                                        const std::string &function_name,
                                        const GeneratorParamValues &generator_params) {
    std::unique_ptr<GeneratorBase> extern_gen = GeneratorRegistry::create(generator_name, generator_params);
    user_assert(extern_gen != nullptr) << "Unknown generator: " << generator_name << "\n";
    // Note that the Generator's target is not set; at present, this shouldn't matter for
    // define_extern() functions, since none of the linkage should vary by Target.
    return extern_gen->call_extern(function_arguments, function_name);
}

}  // namespace Internal
}  // namespace Halide

#endif  // __cplusplus > 199711L
<|endoftext|>


<commit_before>// cfiles, an analysis frontend for the Chemfiles library
// Copyright (C) Guillaume Fraux and contributors -- BSD license

#ifndef CFILES_HISTOGRAM_HPP
#define CFILES_HISTOGRAM_HPP

#include <vector>
#include <cmath>
#include <numeric>
#include <functional>
#include "Errors.hpp"

/// Histogram class
template <class T>
class Histogram: private std::vector<T> {
    using super = std::vector<T>;
public:
    using super::size;
    using super::operator[];
    using super::begin;
    using super::end;

    /// Default constructor
    Histogram(): Histogram(0, 0, 0) {}
    /// Constructor with a specific number of bins `nbins`, and which can hold
    /// data in the `min - max` range.
    Histogram(size_t nbins, double min, double max): super(nbins), min_(min), dr_((max - min) / nbins) {
        static_assert(
            std::is_arithmetic<T>::value,
            "Histogram<T> is only defined for arithmetics types T"
        );
    }

    Histogram(const Histogram&) = default;
    Histogram(Histogram&&) = default;
    Histogram& operator=(const Histogram&) = default;
    Histogram& operator=(Histogram&&) = default;

    /// Get the size of the bins
    double bin_size() const {return dr_;}

    /// Get the minimal value of this histogram
    double min() const {return min_;}

    /// Insert some `data` in the histogram
    void insert(T data) {
        auto bin = std::floor((data - min_) / dr_);
        if (bin >= size() or bin < 0) {
            throw OutOfBoundsError("Element out of boundaries");
        }
        (*this)[bin] += 1;
    }

    /// Normalize the data with a `function` callback, which will be called for
    /// each value. The function should take two arguments being the current
    /// bin index and the data, and return the new data.
    void normalize(std::function<T(size_t, T)> function) {
        for (size_t i=0; i< size(); i++){
            (*this)[i] = function(i, (*this)[i]);
        }
    }
private:
    /// Width of a bin in the Histogram, for arithmetic types only
    double dr_ = 0;
    double min_ = 0;
};

#endif
<commit_msg>Comment for out of boundaries error in Histogram<commit_after>// cfiles, an analysis frontend for the Chemfiles library
// Copyright (C) Guillaume Fraux and contributors -- BSD license

#ifndef CFILES_HISTOGRAM_HPP
#define CFILES_HISTOGRAM_HPP

#include <vector>
#include <cmath>
#include <numeric>
#include <functional>
#include "Errors.hpp"

/// Histogram class
template <class T>
class Histogram: private std::vector<T> {
    using super = std::vector<T>;
public:
    using super::size;
    using super::operator[];
    using super::begin;
    using super::end;

    /// Default constructor
    Histogram(): Histogram(0, 0, 0) {}
    /// Constructor with a specific number of bins `nbins`, and which can hold
    /// data in the `min - max` range.
    Histogram(size_t nbins, double min, double max): super(nbins), min_(min), dr_((max - min) / nbins) {
        static_assert(
            std::is_arithmetic<T>::value,
            "Histogram<T> is only defined for arithmetics types T"
        );
    }

    Histogram(const Histogram&) = default;
    Histogram(Histogram&&) = default;
    Histogram& operator=(const Histogram&) = default;
    Histogram& operator=(Histogram&&) = default;

    /// Get the size of the bins
    double bin_size() const {return dr_;}

    /// Get the minimal value of this histogram
    double min() const {return min_;}

    /// Insert some `data` in the histogram
    void insert(T data) {
        auto bin = std::floor((data - min_) / dr_);
        if (bin >= size() or bin < 0) {
            std::string s = std::to_string(data);
            throw OutOfBoundsError("Element "+ s +" out of boundaries");
        }
        (*this)[bin] += 1;
    }

    /// Normalize the data with a `function` callback, which will be called for
    /// each value. The function should take two arguments being the current
    /// bin index and the data, and return the new data.
    void normalize(std::function<T(size_t, T)> function) {
        for (size_t i=0; i< size(); i++){
            (*this)[i] = function(i, (*this)[i]);
        }
    }
private:
    /// Width of a bin in the Histogram, for arithmetic types only
    double dr_ = 0;
    double min_ = 0;
};

#endif
<|endoftext|>


<commit_before>/*
 * Copyright 2015-2017 Kacper Kasper <kacperkasper@gmail.com>
 * All rights reserved. Distributed under the terms of the MIT license.
 */

#include "Languages.h"

#include <algorithm>
#include <map>
#include <string>

#include <Catalog.h>
#include <FindDirectory.h>
#include <Path.h>
#include <String.h>

#include <SciLexer.h>
#include <yaml.h>

#include "Editor.h"
#include "EditorWindow.h"

#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "Languages"

std::vector<std::string>			Languages::sLanguages;
std::map<std::string, std::string>	Languages::sMenuItems;
std::map<std::string, std::string> 	Languages::sExtensions;

#include <cstdio>
/* static */ bool
Languages::GetLanguageForExtension(const std::string ext, std::string& lang)
{
	lang = "text";
	fprintf(stderr, "ext: %s\n", ext.c_str());
	if(sExtensions.count(ext) > 0) {
		lang = sExtensions[ext];
		return true;
	}
	return false;
}

/* static */ void
Languages::SortAlphabetically()
{
	std::sort(sLanguages.begin(), sLanguages.end());
}

/* static */ void
Languages::ApplyLanguage(Editor* editor, const char* lang)
{
	BPath dataPath;
	find_directory(B_SYSTEM_DATA_DIRECTORY, &dataPath);
	try {
		_ApplyLanguage(editor, lang, dataPath);
	} catch (YAML::BadFile &) {
	}
	find_directory(B_USER_DATA_DIRECTORY, &dataPath);
	try {
		_ApplyLanguage(editor, lang, dataPath);
	} catch (YAML::BadFile &) {
	}
	find_directory(B_SYSTEM_NONPACKAGED_DATA_DIRECTORY, &dataPath);
	try {
		_ApplyLanguage(editor, lang, dataPath);
	} catch (YAML::BadFile &) {
	}
	find_directory(B_USER_NONPACKAGED_DATA_DIRECTORY, &dataPath);
	try {
		_ApplyLanguage(editor, lang, dataPath);
	} catch (YAML::BadFile &) {
	}
}

/* static */ void
Languages::_ApplyLanguage(Editor* editor, const char* lang, const BPath &path)
{
	BPath p(path);
	p.Append(gAppName);
	p.Append("languages");
	p.Append(lang);
	const YAML::Node language = YAML::LoadFile(std::string(p.Path()) + ".yaml");
	int lexerID = language["lexer"].as<int>();
	editor->SendMessage(SCI_SETLEXER, static_cast<uptr_t>(lexerID), 0);

	const YAML::Node properties = language["properties"];
	for(YAML::const_iterator it = properties.begin(); it != properties.end(); ++it) {
		auto name = it->first.as<std::string>();
		auto value = it->second.as<std::string>();
		editor->SendMessage(SCI_SETPROPERTY, (uptr_t) name.c_str(), (sptr_t) value.c_str());
	}

	const YAML::Node keywords = language["keywords"];
	for(YAML::const_iterator it = keywords.begin(); it != keywords.end(); ++it) {
		auto num = it->first.as<int>();
		auto words = it->second.as<std::string>();
		editor->SendMessage(SCI_SETKEYWORDS, num, (sptr_t) words.c_str());
	}
}

/* static */ void
Languages::LoadLanguages()
{
	BPath dataPath;
	find_directory(B_SYSTEM_DATA_DIRECTORY, &dataPath);
	try {
		_LoadLanguages(dataPath);
	} catch (YAML::BadFile &) {
	}
	find_directory(B_USER_DATA_DIRECTORY, &dataPath);
	try {
		_LoadLanguages(dataPath);
	} catch (YAML::BadFile &) {
	}
	find_directory(B_SYSTEM_NONPACKAGED_DATA_DIRECTORY, &dataPath);
	try {
		_LoadLanguages(dataPath);
	} catch (YAML::BadFile &) {
	}
	find_directory(B_USER_NONPACKAGED_DATA_DIRECTORY, &dataPath);
	try {
		_LoadLanguages(dataPath);
	} catch (YAML::BadFile &) {
	}
}

/* static */ void
Languages::_LoadLanguages(const BPath& path)
{
	BPath p(path);
	p.Append(gAppName);
	p.Append("languages");
	const YAML::Node languages = YAML::LoadFile(std::string(p.Path()) + ".yaml");
	for(YAML::const_iterator it = languages.begin(); it != languages.end(); ++it) {
		auto name = it->first.as<std::string>();
		auto menuitem = it->second["name"].as<std::string>();
		auto extensions = it->second["extensions"].as<std::vector<std::string>>();
		for(auto extension : extensions) {
			sExtensions[extension] = name;
		}
		sLanguages.push_back(name);
		sMenuItems[name] = menuitem;
	}
}
<commit_msg>Remove debug leftovers.<commit_after>/*
 * Copyright 2015-2017 Kacper Kasper <kacperkasper@gmail.com>
 * All rights reserved. Distributed under the terms of the MIT license.
 */

#include "Languages.h"

#include <algorithm>
#include <map>
#include <string>

#include <Catalog.h>
#include <FindDirectory.h>
#include <Path.h>
#include <String.h>

#include <SciLexer.h>
#include <yaml.h>

#include "Editor.h"
#include "EditorWindow.h"

#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "Languages"

std::vector<std::string>			Languages::sLanguages;
std::map<std::string, std::string>	Languages::sMenuItems;
std::map<std::string, std::string> 	Languages::sExtensions;

/* static */ bool
Languages::GetLanguageForExtension(const std::string ext, std::string& lang)
{
	lang = "text";
	if(sExtensions.count(ext) > 0) {
		lang = sExtensions[ext];
		return true;
	}
	return false;
}

/* static */ void
Languages::SortAlphabetically()
{
	std::sort(sLanguages.begin(), sLanguages.end());
}

/* static */ void
Languages::ApplyLanguage(Editor* editor, const char* lang)
{
	BPath dataPath;
	find_directory(B_SYSTEM_DATA_DIRECTORY, &dataPath);
	try {
		_ApplyLanguage(editor, lang, dataPath);
	} catch (YAML::BadFile &) {
	}
	find_directory(B_USER_DATA_DIRECTORY, &dataPath);
	try {
		_ApplyLanguage(editor, lang, dataPath);
	} catch (YAML::BadFile &) {
	}
	find_directory(B_SYSTEM_NONPACKAGED_DATA_DIRECTORY, &dataPath);
	try {
		_ApplyLanguage(editor, lang, dataPath);
	} catch (YAML::BadFile &) {
	}
	find_directory(B_USER_NONPACKAGED_DATA_DIRECTORY, &dataPath);
	try {
		_ApplyLanguage(editor, lang, dataPath);
	} catch (YAML::BadFile &) {
	}
}

/* static */ void
Languages::_ApplyLanguage(Editor* editor, const char* lang, const BPath &path)
{
	BPath p(path);
	p.Append(gAppName);
	p.Append("languages");
	p.Append(lang);
	const YAML::Node language = YAML::LoadFile(std::string(p.Path()) + ".yaml");
	int lexerID = language["lexer"].as<int>();
	editor->SendMessage(SCI_SETLEXER, static_cast<uptr_t>(lexerID), 0);

	const YAML::Node properties = language["properties"];
	for(YAML::const_iterator it = properties.begin(); it != properties.end(); ++it) {
		auto name = it->first.as<std::string>();
		auto value = it->second.as<std::string>();
		editor->SendMessage(SCI_SETPROPERTY, (uptr_t) name.c_str(), (sptr_t) value.c_str());
	}

	const YAML::Node keywords = language["keywords"];
	for(YAML::const_iterator it = keywords.begin(); it != keywords.end(); ++it) {
		auto num = it->first.as<int>();
		auto words = it->second.as<std::string>();
		editor->SendMessage(SCI_SETKEYWORDS, num, (sptr_t) words.c_str());
	}
}

/* static */ void
Languages::LoadLanguages()
{
	BPath dataPath;
	find_directory(B_SYSTEM_DATA_DIRECTORY, &dataPath);
	try {
		_LoadLanguages(dataPath);
	} catch (YAML::BadFile &) {
	}
	find_directory(B_USER_DATA_DIRECTORY, &dataPath);
	try {
		_LoadLanguages(dataPath);
	} catch (YAML::BadFile &) {
	}
	find_directory(B_SYSTEM_NONPACKAGED_DATA_DIRECTORY, &dataPath);
	try {
		_LoadLanguages(dataPath);
	} catch (YAML::BadFile &) {
	}
	find_directory(B_USER_NONPACKAGED_DATA_DIRECTORY, &dataPath);
	try {
		_LoadLanguages(dataPath);
	} catch (YAML::BadFile &) {
	}
}

/* static */ void
Languages::_LoadLanguages(const BPath& path)
{
	BPath p(path);
	p.Append(gAppName);
	p.Append("languages");
	const YAML::Node languages = YAML::LoadFile(std::string(p.Path()) + ".yaml");
	for(YAML::const_iterator it = languages.begin(); it != languages.end(); ++it) {
		auto name = it->first.as<std::string>();
		auto menuitem = it->second["name"].as<std::string>();
		auto extensions = it->second["extensions"].as<std::vector<std::string>>();
		for(auto extension : extensions) {
			sExtensions[extension] = name;
		}
		sLanguages.push_back(name);
		sMenuItems[name] = menuitem;
	}
}
<|endoftext|>