<commit_before>/* Copyright (c) 2021 Dennis Wölfing
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/* kernel/src/blockcache.cpp
 * Cached block device.
 */

#include <errno.h>
#include <dennix/kernel/addressspace.h>
#include <dennix/kernel/blockcache.h>
#include <dennix/kernel/interrupts.h>

static void worker(void* device) {
    BlockCacheDevice* dev = (BlockCacheDevice*) device;
    dev->freeUnusedBlocks();
}

BlockCacheDevice::BlockCacheDevice(mode_t mode, dev_t dev)
        : Vnode(mode | S_IFBLK, dev),
        blocks(sizeof(blockBuffer) / sizeof(blockBuffer[0]), blockBuffer) {
    cacheMutex = KTHREAD_MUTEX_INITIALIZER;
    freeList = nullptr;
    leastRecentlyUsed = nullptr;
    mostRecentlyUsed = nullptr;
    workerJob.func = worker;
    workerJob.context = this;
}

bool BlockCacheDevice::isSeekable() {
    return true;
}

void BlockCacheDevice::useBlock(Block* block) {
    // Remove the block from its current location.
    if (block->prevAccessed) {
        block->prevAccessed->nextAccessed = block->nextAccessed;
    } else if (block == leastRecentlyUsed) {
        leastRecentlyUsed = block->nextAccessed;
    }
    if (block->nextAccessed) {
        block->nextAccessed->prevAccessed = block->prevAccessed;
    } else if (block == mostRecentlyUsed) {
        mostRecentlyUsed = block->prevAccessed;
    }

    // Add the block as the most recently used.
    block->prevAccessed = mostRecentlyUsed;
    if (mostRecentlyUsed) {
        mostRecentlyUsed->nextAccessed = block;
    } else {
        leastRecentlyUsed = block;
    }
    mostRecentlyUsed = block;
    block->nextAccessed = nullptr;
}

ssize_t BlockCacheDevice::pread(void* buffer, size_t size, off_t offset,
        int flags) {
    if (size == 0) return 0;

    if (offset < 0) {
        errno = EINVAL;
        return -1;
    }

    AutoLock lock(&mutex);
    if (offset >= stats.st_size) return 0;
    if ((off_t) size > stats.st_size - offset) {
        size = stats.st_size - offset;
    }

    kthread_mutex_lock(&cacheMutex);
    Block* allocatedBlock = nullptr;
    ssize_t bytesRead = 0;
    char* buf = (char*) buffer;

    while (size > 0) {
        uint64_t blockNumber = offset / PAGESIZE;
        off_t blockOffset = blockNumber * PAGESIZE;

        Block* block = blocks.get(blockNumber);
        if (!block) {
            if (!allocatedBlock) {
                kthread_mutex_unlock(&cacheMutex);

                paddr_t physicalAddress = allocateCache();
                if (!physicalAddress) {
                    if (bytesRead) return bytesRead;
                    errno = ENOMEM;
                    return -1;
                }
                vaddr_t address = kernelSpace->mapPhysical(physicalAddress,
                        PAGESIZE, PROT_READ | PROT_WRITE);
                if (!address) {
                    returnCache(physicalAddress);
                    if (bytesRead) return bytesRead;
                    errno = ENOMEM;
                    return -1;
                }
                allocatedBlock = new Block(address, blockNumber);
                if (!allocatedBlock) {
                    kernelSpace->unmapPhysical(address, PAGESIZE);
                    returnCache(physicalAddress);
                    if (bytesRead) return bytesRead;
                    return -1;
                }

                kthread_mutex_lock(&cacheMutex);
            }

            block = blocks.get(blockNumber);

            if (!block) {
                size_t readSize = PAGESIZE;
                if (unlikely(blockOffset + PAGESIZE > stats.st_size)) {
                    // The device ends before the end of the page.
                    readSize = stats.st_size - blockOffset;
                }

                if (!readUncached((void*) allocatedBlock->address, readSize,
                        blockOffset, flags)) {
                    if (!bytesRead) bytesRead = -1;
                    break;
                }

                block = allocatedBlock;
                allocatedBlock = nullptr;
                blocks.add(block);
            }
        }

        useBlock(block);

        size_t readSize = PAGESIZE - (offset & PAGE_MISALIGN);
        if (readSize > size) readSize = size;

        memcpy(buf + bytesRead, (char*) block->address +
                (offset & PAGE_MISALIGN), readSize);
        offset += readSize;
        bytesRead += readSize;
        size -= readSize;
    }

    kthread_mutex_unlock(&cacheMutex);

    if (allocatedBlock) {
        paddr_t physicalAddress = kernelSpace->getPhysicalAddress(
                allocatedBlock->address);
        kernelSpace->unmapPhysical(allocatedBlock->address, PAGESIZE);
        returnCache(physicalAddress);
        delete allocatedBlock;
    }

    return bytesRead;
}

ssize_t BlockCacheDevice::pwrite(const void* buffer, size_t size, off_t offset,
        int flags) {
    if (size == 0) return 0;

    if (offset < 0) {
        errno = EINVAL;
        return -1;
    }

    AutoLock lock(&mutex);
    if (offset >= stats.st_size) {
        errno = ENOSPC;
        return -1;
    }
    if ((off_t) size > stats.st_size - offset) {
        size = stats.st_size - offset;
    }

    kthread_mutex_lock(&cacheMutex);
    Block* allocatedBlock = nullptr;
    ssize_t bytesWritten = 0;
    const char* buf = (const char*) buffer;

    while (size > 0) {
        uint64_t blockNumber = offset / PAGESIZE;
        off_t blockOffset = blockNumber * PAGESIZE;

        Block* block = blocks.get(blockNumber);
        if (!block) {
            if (!allocatedBlock) {
                kthread_mutex_unlock(&cacheMutex);

                paddr_t physicalAddress = allocateCache();
                if (!physicalAddress) {
                    if (bytesWritten) return bytesWritten;
                    errno = ENOMEM;
                    return -1;
                }
                vaddr_t address = kernelSpace->mapPhysical(physicalAddress,
                        PAGESIZE, PROT_READ | PROT_WRITE);
                if (!address) {
                    returnCache(physicalAddress);
                    if (bytesWritten) return bytesWritten;
                    errno = ENOMEM;
                    return -1;
                }
                allocatedBlock = new Block(address, blockNumber);
                if (!allocatedBlock) {
                    kernelSpace->unmapPhysical(address, PAGESIZE);
                    returnCache(physicalAddress);
                    if (bytesWritten) return bytesWritten;
                    return -1;
                }

                kthread_mutex_lock(&cacheMutex);
            }

            block = blocks.get(blockNumber);

            if (!block) {
                // Only read the block from the device if we are not overwriting
                // it completely.
                if (offset != blockOffset || size < PAGESIZE) {
                    size_t readSize = PAGESIZE;
                    if (unlikely(blockOffset + PAGESIZE > stats.st_size)) {
                        // The device ends before the end of the page.
                        readSize = stats.st_size - blockOffset;
                    }

                    if (!readUncached((void*) allocatedBlock->address, readSize,
                            blockOffset, flags)) {
                        if (!bytesWritten) bytesWritten = -1;
                        break;
                    }
                }

                block = allocatedBlock;
                allocatedBlock = nullptr;
                blocks.add(block);
            }
        }

        useBlock(block);

        size_t writeSize = PAGESIZE - (offset & PAGE_MISALIGN);
        if (writeSize > size) writeSize = size;

        memcpy((char*) block->address + (offset & PAGE_MISALIGN),
                buf + bytesWritten, writeSize);

        size_t writeOffset = offset & ~(stats.st_blksize - 1);
        size_t writeLength = ALIGNUP(writeSize, stats.st_blksize);

        if (!writeUncached((char*) block->address + (writeOffset &
                PAGE_MISALIGN), writeLength, writeOffset, flags)) {
            if (bytesWritten == 0) return -1;
            return bytesWritten;
        }

        offset += writeSize;
        bytesWritten += writeSize;
        size -= writeSize;
    }

    kthread_mutex_unlock(&cacheMutex);

    if (allocatedBlock) {
        paddr_t physicalAddress = kernelSpace->getPhysicalAddress(
                allocatedBlock->address);
        kernelSpace->unmapPhysical(allocatedBlock->address, PAGESIZE);
        returnCache(physicalAddress);
        delete allocatedBlock;
    }

    return bytesWritten;
}

void BlockCacheDevice::freeUnusedBlocks() {
    kthread_mutex_lock(&cacheMutex);
    Block* block = freeList;
    freeList = nullptr;
    kthread_mutex_unlock(&cacheMutex);

    while (block) {
        kernelSpace->unmapPhysical(block->address, PAGESIZE);
        Block* nextBlock = block->nextFree;
        delete block;
        block = nextBlock;
    }
}

paddr_t BlockCacheDevice::reclaimCache() {
    AutoLock lock(&cacheMutex);

    Block* block = leastRecentlyUsed;
    if (!block) return 0;

    leastRecentlyUsed = block->nextAccessed;
    if (leastRecentlyUsed) {
        leastRecentlyUsed->prevAccessed = nullptr;
    } else {
        mostRecentlyUsed = nullptr;
    }

    blocks.remove(block->blockNumber);

    block->nextFree = freeList;
    freeList = block;
    if (!block->nextFree) {
        Interrupts::disable();
        WorkerThread::addJob(&workerJob);
        Interrupts::enable();
    }

    paddr_t physicalAddress = kernelSpace->getPhysicalAddress(block->address);
    // We cannot unmap the block yet because the PMM is locked. This will be
    // handled by the worker thread.
    return physicalAddress;
}

BlockCacheDevice::Block::Block(vaddr_t address, uint64_t blockNumber) {
    this->address = address;
    this->blockNumber = blockNumber;
    prevAccessed = nullptr;
    nextAccessed = nullptr;
}
<commit_msg>Fix incorrect type in BlockCacheDevice::pwrite().<commit_after>/* Copyright (c) 2021 Dennis Wölfing
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/* kernel/src/blockcache.cpp
 * Cached block device.
 */

#include <errno.h>
#include <dennix/kernel/addressspace.h>
#include <dennix/kernel/blockcache.h>
#include <dennix/kernel/interrupts.h>

static void worker(void* device) {
    BlockCacheDevice* dev = (BlockCacheDevice*) device;
    dev->freeUnusedBlocks();
}

BlockCacheDevice::BlockCacheDevice(mode_t mode, dev_t dev)
        : Vnode(mode | S_IFBLK, dev),
        blocks(sizeof(blockBuffer) / sizeof(blockBuffer[0]), blockBuffer) {
    cacheMutex = KTHREAD_MUTEX_INITIALIZER;
    freeList = nullptr;
    leastRecentlyUsed = nullptr;
    mostRecentlyUsed = nullptr;
    workerJob.func = worker;
    workerJob.context = this;
}

bool BlockCacheDevice::isSeekable() {
    return true;
}

void BlockCacheDevice::useBlock(Block* block) {
    // Remove the block from its current location.
    if (block->prevAccessed) {
        block->prevAccessed->nextAccessed = block->nextAccessed;
    } else if (block == leastRecentlyUsed) {
        leastRecentlyUsed = block->nextAccessed;
    }
    if (block->nextAccessed) {
        block->nextAccessed->prevAccessed = block->prevAccessed;
    } else if (block == mostRecentlyUsed) {
        mostRecentlyUsed = block->prevAccessed;
    }

    // Add the block as the most recently used.
    block->prevAccessed = mostRecentlyUsed;
    if (mostRecentlyUsed) {
        mostRecentlyUsed->nextAccessed = block;
    } else {
        leastRecentlyUsed = block;
    }
    mostRecentlyUsed = block;
    block->nextAccessed = nullptr;
}

ssize_t BlockCacheDevice::pread(void* buffer, size_t size, off_t offset,
        int flags) {
    if (size == 0) return 0;

    if (offset < 0) {
        errno = EINVAL;
        return -1;
    }

    AutoLock lock(&mutex);
    if (offset >= stats.st_size) return 0;
    if ((off_t) size > stats.st_size - offset) {
        size = stats.st_size - offset;
    }

    kthread_mutex_lock(&cacheMutex);
    Block* allocatedBlock = nullptr;
    ssize_t bytesRead = 0;
    char* buf = (char*) buffer;

    while (size > 0) {
        uint64_t blockNumber = offset / PAGESIZE;
        off_t blockOffset = blockNumber * PAGESIZE;

        Block* block = blocks.get(blockNumber);
        if (!block) {
            if (!allocatedBlock) {
                kthread_mutex_unlock(&cacheMutex);

                paddr_t physicalAddress = allocateCache();
                if (!physicalAddress) {
                    if (bytesRead) return bytesRead;
                    errno = ENOMEM;
                    return -1;
                }
                vaddr_t address = kernelSpace->mapPhysical(physicalAddress,
                        PAGESIZE, PROT_READ | PROT_WRITE);
                if (!address) {
                    returnCache(physicalAddress);
                    if (bytesRead) return bytesRead;
                    errno = ENOMEM;
                    return -1;
                }
                allocatedBlock = new Block(address, blockNumber);
                if (!allocatedBlock) {
                    kernelSpace->unmapPhysical(address, PAGESIZE);
                    returnCache(physicalAddress);
                    if (bytesRead) return bytesRead;
                    return -1;
                }

                kthread_mutex_lock(&cacheMutex);
            }

            block = blocks.get(blockNumber);

            if (!block) {
                size_t readSize = PAGESIZE;
                if (unlikely(blockOffset + PAGESIZE > stats.st_size)) {
                    // The device ends before the end of the page.
                    readSize = stats.st_size - blockOffset;
                }

                if (!readUncached((void*) allocatedBlock->address, readSize,
                        blockOffset, flags)) {
                    if (!bytesRead) bytesRead = -1;
                    break;
                }

                block = allocatedBlock;
                allocatedBlock = nullptr;
                blocks.add(block);
            }
        }

        useBlock(block);

        size_t readSize = PAGESIZE - (offset & PAGE_MISALIGN);
        if (readSize > size) readSize = size;

        memcpy(buf + bytesRead, (char*) block->address +
                (offset & PAGE_MISALIGN), readSize);
        offset += readSize;
        bytesRead += readSize;
        size -= readSize;
    }

    kthread_mutex_unlock(&cacheMutex);

    if (allocatedBlock) {
        paddr_t physicalAddress = kernelSpace->getPhysicalAddress(
                allocatedBlock->address);
        kernelSpace->unmapPhysical(allocatedBlock->address, PAGESIZE);
        returnCache(physicalAddress);
        delete allocatedBlock;
    }

    return bytesRead;
}

ssize_t BlockCacheDevice::pwrite(const void* buffer, size_t size, off_t offset,
        int flags) {
    if (size == 0) return 0;

    if (offset < 0) {
        errno = EINVAL;
        return -1;
    }

    AutoLock lock(&mutex);
    if (offset >= stats.st_size) {
        errno = ENOSPC;
        return -1;
    }
    if ((off_t) size > stats.st_size - offset) {
        size = stats.st_size - offset;
    }

    kthread_mutex_lock(&cacheMutex);
    Block* allocatedBlock = nullptr;
    ssize_t bytesWritten = 0;
    const char* buf = (const char*) buffer;

    while (size > 0) {
        uint64_t blockNumber = offset / PAGESIZE;
        off_t blockOffset = blockNumber * PAGESIZE;

        Block* block = blocks.get(blockNumber);
        if (!block) {
            if (!allocatedBlock) {
                kthread_mutex_unlock(&cacheMutex);

                paddr_t physicalAddress = allocateCache();
                if (!physicalAddress) {
                    if (bytesWritten) return bytesWritten;
                    errno = ENOMEM;
                    return -1;
                }
                vaddr_t address = kernelSpace->mapPhysical(physicalAddress,
                        PAGESIZE, PROT_READ | PROT_WRITE);
                if (!address) {
                    returnCache(physicalAddress);
                    if (bytesWritten) return bytesWritten;
                    errno = ENOMEM;
                    return -1;
                }
                allocatedBlock = new Block(address, blockNumber);
                if (!allocatedBlock) {
                    kernelSpace->unmapPhysical(address, PAGESIZE);
                    returnCache(physicalAddress);
                    if (bytesWritten) return bytesWritten;
                    return -1;
                }

                kthread_mutex_lock(&cacheMutex);
            }

            block = blocks.get(blockNumber);

            if (!block) {
                // Only read the block from the device if we are not overwriting
                // it completely.
                if (offset != blockOffset || size < PAGESIZE) {
                    size_t readSize = PAGESIZE;
                    if (unlikely(blockOffset + PAGESIZE > stats.st_size)) {
                        // The device ends before the end of the page.
                        readSize = stats.st_size - blockOffset;
                    }

                    if (!readUncached((void*) allocatedBlock->address, readSize,
                            blockOffset, flags)) {
                        if (!bytesWritten) bytesWritten = -1;
                        break;
                    }
                }

                block = allocatedBlock;
                allocatedBlock = nullptr;
                blocks.add(block);
            }
        }

        useBlock(block);

        size_t writeSize = PAGESIZE - (offset & PAGE_MISALIGN);
        if (writeSize > size) writeSize = size;

        memcpy((char*) block->address + (offset & PAGE_MISALIGN),
                buf + bytesWritten, writeSize);

        off_t writeOffset = offset & ~(stats.st_blksize - 1);
        size_t writeLength = ALIGNUP(writeSize, stats.st_blksize);

        if (!writeUncached((char*) block->address + (writeOffset &
                PAGE_MISALIGN), writeLength, writeOffset, flags)) {
            if (bytesWritten == 0) return -1;
            return bytesWritten;
        }

        offset += writeSize;
        bytesWritten += writeSize;
        size -= writeSize;
    }

    kthread_mutex_unlock(&cacheMutex);

    if (allocatedBlock) {
        paddr_t physicalAddress = kernelSpace->getPhysicalAddress(
                allocatedBlock->address);
        kernelSpace->unmapPhysical(allocatedBlock->address, PAGESIZE);
        returnCache(physicalAddress);
        delete allocatedBlock;
    }

    return bytesWritten;
}

void BlockCacheDevice::freeUnusedBlocks() {
    kthread_mutex_lock(&cacheMutex);
    Block* block = freeList;
    freeList = nullptr;
    kthread_mutex_unlock(&cacheMutex);

    while (block) {
        kernelSpace->unmapPhysical(block->address, PAGESIZE);
        Block* nextBlock = block->nextFree;
        delete block;
        block = nextBlock;
    }
}

paddr_t BlockCacheDevice::reclaimCache() {
    AutoLock lock(&cacheMutex);

    Block* block = leastRecentlyUsed;
    if (!block) return 0;

    leastRecentlyUsed = block->nextAccessed;
    if (leastRecentlyUsed) {
        leastRecentlyUsed->prevAccessed = nullptr;
    } else {
        mostRecentlyUsed = nullptr;
    }

    blocks.remove(block->blockNumber);

    block->nextFree = freeList;
    freeList = block;
    if (!block->nextFree) {
        Interrupts::disable();
        WorkerThread::addJob(&workerJob);
        Interrupts::enable();
    }

    paddr_t physicalAddress = kernelSpace->getPhysicalAddress(block->address);
    // We cannot unmap the block yet because the PMM is locked. This will be
    // handled by the worker thread.
    return physicalAddress;
}

BlockCacheDevice::Block::Block(vaddr_t address, uint64_t blockNumber) {
    this->address = address;
    this->blockNumber = blockNumber;
    prevAccessed = nullptr;
    nextAccessed = nullptr;
}
<|endoftext|>


<commit_before>//----------------------------  mapping_02.cc  ---------------------------
//    $Id: bem.cc 22693 2010-11-11 20:11:47Z kanschat $
//    Version: $Name$
//
//    Copyright (C) 2010, 2011 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  mapping_02.cc  ---------------------------

// like _01, but use a quadratic mapping. since we now map line segments to
// curves, the normal vectors at different quadrature points should no longer
// be parallel

#include "../tests.h"

#include <base/quadrature_lib.h>
#include <grid/tria.h>
#include <grid/grid_generator.h>
#include <grid/tria_boundary_lib.h>
#include <grid/grid_out.h>
#include <grid/grid_tools.h>
#include <fe/fe_values.h>
#include <fe/fe_q.h>
#include <fe/mapping_q.h>

template <int dim>
void test (unsigned int degree)
{
  Triangulation<dim-1, dim> mesh;
  GridGenerator::hyper_cube(mesh);

  QGauss<dim-1> quadrature(dim == 2 ? 3 : 2);
  MappingQ<dim-1,dim> mapping(degree);
  Point<dim> p;

				   // Try to project a point on the
				   // surface
  for(unsigned int i=0; i<dim; ++i)
    p[i] = .2;

  Point<dim-1> q =
    mapping.transform_real_to_unit_cell(mesh.begin_active(), p);

  deallog << "Mapping Q("<< degree<< "): P: " << p
	  << ", on unit: " << q << std::endl;

}

int main ()
{
  std::ofstream logfile("mapping_03/output");
  deallog.attach(logfile);
  deallog.depth_console(0);

  test<2> (1);
  test<2> (2);

  test<3> (1);
  test<3> (2);

  return 0;
}
<commit_msg>Make include path future proof.<commit_after>//----------------------------  mapping_02.cc  ---------------------------
//    $Id: bem.cc 22693 2010-11-11 20:11:47Z kanschat $
//    Version: $Name$
//
//    Copyright (C) 2010, 2011 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  mapping_02.cc  ---------------------------

// like _01, but use a quadratic mapping. since we now map line segments to
// curves, the normal vectors at different quadrature points should no longer
// be parallel

#include "../tests.h"

#include <deal.II/base/quadrature_lib.h>
#include <deal.II/grid/tria.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/grid/tria_boundary_lib.h>
#include <deal.II/grid/grid_out.h>
#include <deal.II/grid/grid_tools.h>
#include <deal.II/fe/fe_values.h>
#include <deal.II/fe/fe_q.h>
#include <deal.II/fe/mapping_q.h>

template <int dim>
void test (unsigned int degree)
{
  Triangulation<dim-1, dim> mesh;
  GridGenerator::hyper_cube(mesh);

  QGauss<dim-1> quadrature(dim == 2 ? 3 : 2);
  MappingQ<dim-1,dim> mapping(degree);
  Point<dim> p;

				   // Try to project a point on the
				   // surface
  for(unsigned int i=0; i<dim; ++i)
    p[i] = .2;

  Point<dim-1> q =
    mapping.transform_real_to_unit_cell(mesh.begin_active(), p);

  deallog << "Mapping Q("<< degree<< "): P: " << p
	  << ", on unit: " << q << std::endl;

}

int main ()
{
  std::ofstream logfile("mapping_03/output");
  deallog.attach(logfile);
  deallog.depth_console(0);

  test<2> (1);
  test<2> (2);

  test<3> (1);
  test<3> (2);

  return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2011-2014 Intel Corporation. All rights reserved.
 *
 * 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.
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "decodeinputavformat.h"
#include "common/common_def.h"
#include "common/log.h"
#include <Yami.h>

DecodeInputAvFormat::DecodeInputAvFormat()
:m_format(NULL),m_videoId(-1), m_codecId(AV_CODEC_ID_NONE), m_isEos(true)
{
    av_register_all();

    av_init_packet(&m_packet);
}

bool DecodeInputAvFormat::initInput(const char* fileName)
{
    uint16_t width = 0, height = 0;
    int ret = avformat_open_input(&m_format, fileName, NULL, NULL);
    if (ret)
        goto error;
    uint32_t i;
    for (i = 0; i < m_format->nb_streams; ++i) {
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 33, 100)
        AVCodecParameters* codec = m_format->streams[i]->codecpar;
#else
        AVCodecContext* codec = m_format->streams[i]->codec;
#endif
        //VP9: width and height of the IVF header,VP8: width and height is zero
        if (AVMEDIA_TYPE_VIDEO == codec->codec_type) {
            width = codec->width;
            height = codec->height;
            break;
        }
    }

    ret = avformat_find_stream_info(m_format, NULL);
    if (ret < 0)
        goto error;
    for (i = 0; i < m_format->nb_streams; i++)
    {
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 33, 100)
        AVCodecParameters* codec = m_format->streams[i]->codecpar;
#else
        AVCodecContext* codec = m_format->streams[i]->codec;
#endif
        if (AVMEDIA_TYPE_VIDEO == codec->codec_type) {
            m_codecId = codec->codec_id;
            if (codec->extradata && codec->extradata_size)
                m_codecData.append((char*)codec->extradata, codec->extradata_size);
            m_videoId = i;
            //VP9: display_width and display_height of the first frame
            if (codec->width > width)
                width = codec->width;
            if (codec->height > height)
                height = codec->height;
            setResolution(width, height);
            break;
        }
    }
    if (i == m_format->nb_streams) {
        ERROR("no video stream");
        goto error;
    }
    m_isEos = false;
    return true;
error:
    if (m_format)
        avformat_close_input(&m_format);
    return false;

}

struct MimeEntry
{
    AVCodecID id;
    const char* mime;
};

static const MimeEntry MimeEntrys[] = {
    AV_CODEC_ID_MPEG2VIDEO, YAMI_MIME_MPEG2,
    AV_CODEC_ID_VP8, YAMI_MIME_VP8,

#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(54, 40, 0)
    AV_CODEC_ID_VP9, YAMI_MIME_VP9,
#endif

    AV_CODEC_ID_H264, YAMI_MIME_H264,
    AV_CODEC_ID_H265, YAMI_MIME_H265,
    AV_CODEC_ID_WMV3, YAMI_MIME_VC1,
    AV_CODEC_ID_VC1, YAMI_MIME_VC1
};

const char * DecodeInputAvFormat::getMimeType()
{
    for (size_t i = 0; i < N_ELEMENTS(MimeEntrys); i++) {
        if (MimeEntrys[i].id == m_codecId)
            return MimeEntrys[i].mime;
    }
    return "unknow";
}

bool DecodeInputAvFormat::getNextDecodeUnit(VideoDecodeBuffer &inputBuffer)
{
    if (!m_format || m_isEos)
        return false;
    int ret;
    while (1) {
        //free old packet
        av_packet_unref(&m_packet);

        ret = av_read_frame(m_format, &m_packet);
        if (ret) {
            m_isEos = true;
            return false;
        }
        if (m_packet.stream_index == m_videoId) {
            memset(&inputBuffer, 0, sizeof(inputBuffer));
            inputBuffer.data = m_packet.data;
            inputBuffer.size = m_packet.size;
            inputBuffer.timeStamp = m_packet.dts;
            return true;
        }
    }
    return false;
}

const string& DecodeInputAvFormat::getCodecData()
{
    return m_codecData;
}

DecodeInputAvFormat::~DecodeInputAvFormat()
{
    if (m_format) {
        av_packet_unref(&m_packet);
        avformat_close_input(&m_format);
    }

}
<commit_msg>avformat: be compatible with all version ffmpeg<commit_after>/*
 * Copyright (C) 2011-2014 Intel Corporation. All rights reserved.
 *
 * 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.
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "decodeinputavformat.h"
#include "common/common_def.h"
#include "common/log.h"
#include <Yami.h>

#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 39, 100)
#define av_packet_unref av_free_packet
#endif

DecodeInputAvFormat::DecodeInputAvFormat()
:m_format(NULL),m_videoId(-1), m_codecId(AV_CODEC_ID_NONE), m_isEos(true)
{
    av_register_all();

    av_init_packet(&m_packet);
}

bool DecodeInputAvFormat::initInput(const char* fileName)
{
    uint16_t width = 0, height = 0;
    int ret = avformat_open_input(&m_format, fileName, NULL, NULL);
    if (ret)
        goto error;
    uint32_t i;
    for (i = 0; i < m_format->nb_streams; ++i) {
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 33, 100)
        AVCodecParameters* codec = m_format->streams[i]->codecpar;
#else
        AVCodecContext* codec = m_format->streams[i]->codec;
#endif
        //VP9: width and height of the IVF header,VP8: width and height is zero
        if (AVMEDIA_TYPE_VIDEO == codec->codec_type) {
            width = codec->width;
            height = codec->height;
            break;
        }
    }

    ret = avformat_find_stream_info(m_format, NULL);
    if (ret < 0)
        goto error;
    for (i = 0; i < m_format->nb_streams; i++)
    {
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 33, 100)
        AVCodecParameters* codec = m_format->streams[i]->codecpar;
#else
        AVCodecContext* codec = m_format->streams[i]->codec;
#endif
        if (AVMEDIA_TYPE_VIDEO == codec->codec_type) {
            m_codecId = codec->codec_id;
            if (codec->extradata && codec->extradata_size)
                m_codecData.append((char*)codec->extradata, codec->extradata_size);
            m_videoId = i;
            //VP9: display_width and display_height of the first frame
            if (codec->width > width)
                width = codec->width;
            if (codec->height > height)
                height = codec->height;
            setResolution(width, height);
            break;
        }
    }
    if (i == m_format->nb_streams) {
        ERROR("no video stream");
        goto error;
    }
    m_isEos = false;
    return true;
error:
    if (m_format)
        avformat_close_input(&m_format);
    return false;

}

struct MimeEntry
{
    AVCodecID id;
    const char* mime;
};

static const MimeEntry MimeEntrys[] = {
    AV_CODEC_ID_MPEG2VIDEO, YAMI_MIME_MPEG2,
    AV_CODEC_ID_VP8, YAMI_MIME_VP8,

#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(54, 40, 0)
    AV_CODEC_ID_VP9, YAMI_MIME_VP9,
#endif

    AV_CODEC_ID_H264, YAMI_MIME_H264,
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 39, 100)
    AV_CODEC_ID_H265, YAMI_MIME_H265,
#endif
    AV_CODEC_ID_WMV3, YAMI_MIME_VC1,
    AV_CODEC_ID_VC1, YAMI_MIME_VC1
};

const char * DecodeInputAvFormat::getMimeType()
{
    for (size_t i = 0; i < N_ELEMENTS(MimeEntrys); i++) {
        if (MimeEntrys[i].id == m_codecId)
            return MimeEntrys[i].mime;
    }
    return "unknow";
}

bool DecodeInputAvFormat::getNextDecodeUnit(VideoDecodeBuffer &inputBuffer)
{
    if (!m_format || m_isEos)
        return false;
    int ret;
    while (1) {
        //free old packet
        av_packet_unref(&m_packet);

        ret = av_read_frame(m_format, &m_packet);
        if (ret) {
            m_isEos = true;
            return false;
        }
        if (m_packet.stream_index == m_videoId) {
            memset(&inputBuffer, 0, sizeof(inputBuffer));
            inputBuffer.data = m_packet.data;
            inputBuffer.size = m_packet.size;
            inputBuffer.timeStamp = m_packet.dts;
            return true;
        }
    }
    return false;
}

const string& DecodeInputAvFormat::getCodecData()
{
    return m_codecData;
}

DecodeInputAvFormat::~DecodeInputAvFormat()
{
    if (m_format) {
        av_packet_unref(&m_packet);
        avformat_close_input(&m_format);
    }

}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "id.h"
#include "coreconstants.h"
#include "icontext.h"

#include <utils/qtcassert.h>

#include <QtCore/QHash>

namespace Core {

/*!
    \class Core::Id

    \brief The class Id encapsulates an identifier. It is used as a type-safe
    helper class instead of a \c QString or \c QByteArray. The internal
    representation of the id is assumed to be plain 7-bit-clean ASCII.

*/

static int lastUid = 0;
static QVector<QByteArray> stringFromId;
static QHash<QByteArray, int> idFromString;

static int theId(const QByteArray &ba)
{
    QTC_CHECK(!ba.isEmpty());
    int res = idFromString.value(ba);
    if (res == 0) {
        if (lastUid == 0)
            stringFromId.append(QByteArray());
        res = ++lastUid;
        idFromString[ba] = res;
        stringFromId.append(ba);
    }
    return res;
}

Id::Id(const char *name)
    : m_id(theId(name))
{}

Id::Id(const QString &name)
   : m_id(theId(name.toLatin1()))
{}

QByteArray Id::name() const
{
    return stringFromId.at(m_id);
}

QString Id::toString() const
{
    return QString::fromLatin1(stringFromId[m_id]);
}

Context::Context(const char *id, int offset)
{
    d.append(Id(QLatin1String(id) + QString::number(offset)).uniqueIdentifier());
}

void Context::add(const char *id)
{
    d.append(Id(id).uniqueIdentifier());
}

bool Context::contains(const char *id) const
{
    return d.contains(Id(id).uniqueIdentifier());
}

} // namespace Core
<commit_msg>core: prevent allocations when looking up an existing Core::Id<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "id.h"
#include "coreconstants.h"
#include "icontext.h"

#include <utils/qtcassert.h>

#include <QtCore/QHash>

namespace Core {

/*!
    \class Core::Id

    \brief The class Id encapsulates an identifier. It is used as a type-safe
    helper class instead of a \c QString or \c QByteArray. The internal
    representation of the id is assumed to be plain 7-bit-clean ASCII.

*/

class StringHolder
{
public:
    explicit StringHolder(const char *s)
        : str(s)
    {
        n = strlen(s);
        int m = n;
        h = 0;
        while (m--) {
            h = (h << 4) + *s++;
            h ^= (h & 0xf0000000) >> 23;
            h &= 0x0fffffff;
        }
    }
    int n;
    const char *str;
    uint h;
};

static bool operator==(const StringHolder &sh1, const StringHolder &sh2)
{
    // sh.n is unlikely to discriminate better than the hash.
    return sh1.h == sh2.h && strcmp(sh1.str, sh1.str) == 0;
}

static uint qHash(const StringHolder &sh)
{
    return sh.h;
}

struct IdCache : public QHash<StringHolder, int>
{
#ifndef QTC_ALLOW_STATIC_LEAKS
    ~IdCache()
    {
        for (IdCache::iterator it = begin(); it != end(); ++it)
            free(const_cast<char *>(it.key().str));
    }
#endif
};

static int lastUid = 0;
static QVector<QByteArray> stringFromId;
static IdCache idFromString;

static int theId(const char *str)
{
    QTC_ASSERT(str && *str, return 0);
    StringHolder sh(str);
    int res = idFromString.value(sh, 0);
    if (res == 0) {
        if (lastUid == 0)
            stringFromId.append(QByteArray());
        res = ++lastUid;
        sh.str = strdup(sh.str);
        idFromString[sh] = res;
        stringFromId.append(QByteArray::fromRawData(sh.str, sh.n));
    }
    return res;
}

Id::Id(const char *name)
    : m_id(theId(name))
{}

Id::Id(const QString &name)
   : m_id(theId(name.toLatin1()))
{}

QByteArray Id::name() const
{
    return stringFromId.at(m_id);
}

QString Id::toString() const
{
    return QString::fromLatin1(stringFromId[m_id]);
}

Context::Context(const char *id, int offset)
{
    d.append(Id(QLatin1String(id) + QString::number(offset)).uniqueIdentifier());
}

void Context::add(const char *id)
{
    d.append(Id(id).uniqueIdentifier());
}

bool Context::contains(const char *id) const
{
    return d.contains(Id(id).uniqueIdentifier());
}

} // namespace Core
<|endoftext|>


<commit_before>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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.
 */
/*
 * Copyright (C) 2020 ScyllaDB Ltd.
 */

#include <seastar/testing/perf_tests.hh>
#include <seastar/core/sharded.hh>
#include <seastar/core/thread.hh>
#include <seastar/core/fair_queue.hh>
#include <seastar/core/semaphore.hh>
#include <boost/range/irange.hpp>

struct local_fq_and_class {
    seastar::fair_queue fq;
    seastar::priority_class_ptr pclass;
    unsigned executed = 0;

    local_fq_and_class(seastar::fair_queue::config cfg)
        : fq(std::move(cfg))
        , pclass(fq.register_priority_class(1))
    {}

    ~local_fq_and_class() {
        fq.unregister_priority_class(pclass);
    }
};

struct perf_fair_queue {

    static constexpr unsigned requests_to_dispatch = 1000;

    seastar::fair_queue::config cfg;
    seastar::sharded<local_fq_and_class> local_fq;

    seastar::fair_queue shared_fq;
    std::vector<priority_class_ptr> shared_pclass;

    uint64_t shared_executed = 0;
    uint64_t shared_acked = 0;

    perf_fair_queue()
        : cfg({ std::chrono::milliseconds(100), 1, 1 })
        , shared_fq(cfg)
    {
        local_fq.start(cfg).get();
        for (unsigned i = 0; i < smp::count; ++i) {
            shared_pclass.push_back(shared_fq.register_priority_class(1));
        }
    }

    ~perf_fair_queue() {
        local_fq.stop().get();
        for (auto& pc : shared_pclass) {
            shared_fq.unregister_priority_class(pc);
        }
    }
};

PERF_TEST_F(perf_fair_queue, contended_local)
{
    auto invokers = local_fq.invoke_on_all([] (local_fq_and_class& local) {
        local.executed = 0;

        return parallel_for_each(boost::irange(0u, requests_to_dispatch), [&local] (unsigned dummy) {
            local.fq.queue(local.pclass, seastar::fair_queue_ticket{1, 1}, [&local] {
                local.executed++;
                local.fq.notify_requests_finished(seastar::fair_queue_ticket{1, 1});
            });
            return make_ready_future<>();
        });
    });

    auto collectors = local_fq.invoke_on_all([] (local_fq_and_class& local) {
        return do_until([&local] { return local.executed == requests_to_dispatch; }, [&local] {
            local.fq.dispatch_requests();
            return make_ready_future<>();
        });
    });

    return when_all_succeed(std::move(invokers), std::move(collectors)).discard_result();
}

PERF_TEST_F(perf_fair_queue, contended_shared)
{
    shared_acked = 0;
    shared_executed = 0;
    auto invokers = local_fq.invoke_on_all([this, coordinator = this_shard_id()] (local_fq_and_class& dummy) {
        return parallel_for_each(boost::irange(0u, requests_to_dispatch), [this, coordinator] (unsigned dummy) {
            return smp::submit_to(coordinator, [this] {
                shared_fq.queue(shared_pclass[this_shard_id()], seastar::fair_queue_ticket{1, 1}, [this] {
                    shared_executed++;
                });
                return make_ready_future<>();
            });
        });
    });

    auto collectors = do_until([this] { return shared_acked == requests_to_dispatch * smp::count; }, [this] {
        shared_fq.dispatch_requests();
        uint32_t pending_ack = shared_executed - shared_acked;
        shared_acked = shared_executed;
        shared_fq.notify_requests_finished(seastar::fair_queue_ticket{pending_ack, pending_ack}, pending_ack);
        return make_ready_future<>();
    });
    return when_all_succeed(std::move(invokers), std::move(collectors)).discard_result();
}
PERF_TEST_F(perf_fair_queue, contended_shared_amortized)
{
    shared_acked = 0;
    shared_executed = 0;
    auto invokers = local_fq.invoke_on_all([this, coordinator = this_shard_id()] (local_fq_and_class& dummy) {
        return smp::submit_to(coordinator, [this] {
            return parallel_for_each(boost::irange(0u, requests_to_dispatch), [this] (unsigned dummy) {
                shared_fq.queue(shared_pclass[this_shard_id()], seastar::fair_queue_ticket{1, 1}, [this] {
                    shared_executed++;
                });
                return make_ready_future<>();
            });
        });
    });

    auto collectors = do_until([this] { return shared_acked == requests_to_dispatch * smp::count; }, [this] {
        shared_fq.dispatch_requests();
        uint32_t pending_ack = shared_executed - shared_acked;
        shared_acked = shared_executed;
        shared_fq.notify_requests_finished(seastar::fair_queue_ticket{pending_ack, pending_ack}, pending_ack);
        return make_ready_future<>();
    });
    return when_all_succeed(std::move(invokers), std::move(collectors)).discard_result();
}
<commit_msg>tests: Fix perf fair queue stuck<commit_after>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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.
 */
/*
 * Copyright (C) 2020 ScyllaDB Ltd.
 */

#include <seastar/testing/perf_tests.hh>
#include <seastar/core/sharded.hh>
#include <seastar/core/thread.hh>
#include <seastar/core/fair_queue.hh>
#include <seastar/core/semaphore.hh>
#include <boost/range/irange.hpp>

struct local_fq_and_class {
    seastar::fair_queue fq;
    seastar::priority_class_ptr pclass;
    unsigned executed = 0;

    local_fq_and_class(seastar::fair_queue::config cfg)
        : fq(std::move(cfg))
        , pclass(fq.register_priority_class(1))
    {}

    ~local_fq_and_class() {
        fq.unregister_priority_class(pclass);
    }
};

struct perf_fair_queue {

    static constexpr unsigned requests_to_dispatch = 1000;

    seastar::fair_queue::config cfg;
    seastar::sharded<local_fq_and_class> local_fq;

    seastar::fair_queue shared_fq;
    std::vector<priority_class_ptr> shared_pclass;

    uint64_t shared_executed = 0;
    uint64_t shared_acked = 0;

    perf_fair_queue()
        : cfg({ std::chrono::milliseconds(100), 1, 1 })
        , shared_fq(cfg)
    {
        local_fq.start(cfg).get();
        for (unsigned i = 0; i < smp::count; ++i) {
            shared_pclass.push_back(shared_fq.register_priority_class(1));
        }
    }

    ~perf_fair_queue() {
        local_fq.stop().get();
        for (auto& pc : shared_pclass) {
            shared_fq.unregister_priority_class(pc);
        }
    }
};

PERF_TEST_F(perf_fair_queue, contended_local)
{
    auto invokers = local_fq.invoke_on_all([] (local_fq_and_class& local) {
        return parallel_for_each(boost::irange(0u, requests_to_dispatch), [&local] (unsigned dummy) {
            local.fq.queue(local.pclass, seastar::fair_queue_ticket{1, 1}, [&local] {
                local.executed++;
                local.fq.notify_requests_finished(seastar::fair_queue_ticket{1, 1});
            });
            return make_ready_future<>();
        });
    });

    auto collectors = local_fq.invoke_on_all([] (local_fq_and_class& local) {
        // Zeroing this counter must be here, otherwise should the collectors win the
        // execution order in when_all_succeed(), the do_until()'s stopping callback
        // would return true immediately and the queue would not be dispatched.
        //
        // At the same time, although this counter is incremented by the lambda from
        // invokers, it's not called until the fq.dispatch_requests() is, so there's no
        // opposite problem if zeroing it here.
        local.executed = 0;

        return do_until([&local] { return local.executed == requests_to_dispatch; }, [&local] {
            local.fq.dispatch_requests();
            return make_ready_future<>();
        });
    });

    return when_all_succeed(std::move(invokers), std::move(collectors)).discard_result();
}

PERF_TEST_F(perf_fair_queue, contended_shared)
{
    shared_acked = 0;
    shared_executed = 0;
    auto invokers = local_fq.invoke_on_all([this, coordinator = this_shard_id()] (local_fq_and_class& dummy) {
        return parallel_for_each(boost::irange(0u, requests_to_dispatch), [this, coordinator] (unsigned dummy) {
            return smp::submit_to(coordinator, [this] {
                shared_fq.queue(shared_pclass[this_shard_id()], seastar::fair_queue_ticket{1, 1}, [this] {
                    shared_executed++;
                });
                return make_ready_future<>();
            });
        });
    });

    auto collectors = do_until([this] { return shared_acked == requests_to_dispatch * smp::count; }, [this] {
        shared_fq.dispatch_requests();
        uint32_t pending_ack = shared_executed - shared_acked;
        shared_acked = shared_executed;
        shared_fq.notify_requests_finished(seastar::fair_queue_ticket{pending_ack, pending_ack}, pending_ack);
        return make_ready_future<>();
    });
    return when_all_succeed(std::move(invokers), std::move(collectors)).discard_result();
}
PERF_TEST_F(perf_fair_queue, contended_shared_amortized)
{
    shared_acked = 0;
    shared_executed = 0;
    auto invokers = local_fq.invoke_on_all([this, coordinator = this_shard_id()] (local_fq_and_class& dummy) {
        return smp::submit_to(coordinator, [this] {
            return parallel_for_each(boost::irange(0u, requests_to_dispatch), [this] (unsigned dummy) {
                shared_fq.queue(shared_pclass[this_shard_id()], seastar::fair_queue_ticket{1, 1}, [this] {
                    shared_executed++;
                });
                return make_ready_future<>();
            });
        });
    });

    auto collectors = do_until([this] { return shared_acked == requests_to_dispatch * smp::count; }, [this] {
        shared_fq.dispatch_requests();
        uint32_t pending_ack = shared_executed - shared_acked;
        shared_acked = shared_executed;
        shared_fq.notify_requests_finished(seastar::fair_queue_ticket{pending_ack, pending_ack}, pending_ack);
        return make_ready_future<>();
    });
    return when_all_succeed(std::move(invokers), std::move(collectors)).discard_result();
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015-2016 Alexander Saprykin <xelfium@gmail.com>
 *
 * This program 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 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
 */

#ifndef PLIBSYS_TESTS_STATIC
#  define BOOST_TEST_DYN_LINK
#endif

#define BOOST_TEST_MODULE plibraryloader_test

#include "plibsys.h"

#include <stdio.h>

#ifdef PLIBSYS_TESTS_STATIC
#  include <boost/test/included/unit_test.hpp>
#else
#  include <boost/test/unit_test.hpp>
#endif

extern "C" ppointer pmem_alloc (psize nbytes)
{
	P_UNUSED (nbytes);
	return (ppointer) NULL;
}

extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
{
	P_UNUSED (block);
	P_UNUSED (nbytes);
	return (ppointer) NULL;
}

extern "C" void pmem_free (ppointer block)
{
	P_UNUSED (block);
}

BOOST_AUTO_TEST_SUITE (BOOST_TEST_MODULE)

BOOST_AUTO_TEST_CASE (plibraryloader_nomem_test)
{
	p_libsys_init ();

	/* We assume that 2nd argument is ourself library path */
	BOOST_REQUIRE (boost::unit_test::framework::master_test_suite().argc == 2);

	/* Cleanup from previous run */
	p_file_remove ("." P_DIR_SEPARATOR "p_empty_file.txt", NULL);

	FILE *file = fopen ("." P_DIR_SEPARATOR "p_empty_file.txt", "w");
	BOOST_CHECK (file != NULL);
	BOOST_CHECK (fclose (file) == 0);

	PMemVTable vtable;

	vtable.free	= pmem_free;
	vtable.malloc	= pmem_alloc;
	vtable.realloc	= pmem_realloc;

	BOOST_CHECK (p_mem_set_vtable (&vtable) == TRUE);

	BOOST_CHECK (p_library_loader_new ("." P_DIR_SEPARATOR "p_empty_file.txt") == NULL);
	BOOST_CHECK (p_library_loader_new (boost::unit_test::framework::master_test_suite().argv[1]) == NULL);

	vtable.malloc	= (ppointer (*)(psize)) malloc;
	vtable.realloc	= (ppointer (*)(ppointer, psize)) realloc;
	vtable.free	= (void (*)(ppointer)) free;

	BOOST_CHECK (p_mem_set_vtable (&vtable) == TRUE);

	BOOST_CHECK (p_file_remove ("." P_DIR_SEPARATOR "p_empty_file.txt", NULL) == TRUE);

	p_libsys_shutdown ();
}

BOOST_AUTO_TEST_CASE (plibraryloader_general_test)
{
	PLibraryLoader	*loader;
	pchar		*err_msg;
	void		(*shutdown_func) (void);

	p_libsys_init ();

	/* We assume that 2nd argument is ourself library path */
	BOOST_REQUIRE (boost::unit_test::framework::master_test_suite().argc == 2);

	/* Invalid usage */
	BOOST_CHECK (p_library_loader_new (NULL) == NULL);
	BOOST_CHECK (p_library_loader_new ("./unexistent_file.nofile") == NULL);
	BOOST_CHECK (p_library_loader_get_symbol (NULL, NULL) == NULL);
	BOOST_CHECK (p_library_loader_get_symbol (NULL, "unexistent_symbol") == NULL);

	p_library_loader_free (NULL);

	/* General tests */
	err_msg = p_library_loader_get_last_error ();
	p_free (err_msg);

	loader = p_library_loader_new (boost::unit_test::framework::master_test_suite().argv[1]);
	BOOST_REQUIRE (loader != NULL);

	BOOST_CHECK (p_library_loader_get_symbol (loader, "there_is_no_such_a_symbol") == (PFuncAddr) NULL);

	err_msg = p_library_loader_get_last_error ();
	BOOST_CHECK (err_msg != NULL);
	p_free (err_msg);

	shutdown_func = (void (*) (void)) p_library_loader_get_symbol (loader, "p_libsys_shutdown");

	if (shutdown_func == NULL)
		shutdown_func = (void (*) (void)) p_library_loader_get_symbol (loader, "_p_libsys_shutdown");

	BOOST_REQUIRE (shutdown_func != NULL);

	err_msg = p_library_loader_get_last_error ();
	p_free (err_msg);

	p_library_loader_free (loader);

	/* We have already loaded reference to ourself library, it's OK */
	shutdown_func ();
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>tests: Silent message box on Windows<commit_after>/*
 * Copyright (C) 2015-2016 Alexander Saprykin <xelfium@gmail.com>
 *
 * This program 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 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
 */

#ifndef PLIBSYS_TESTS_STATIC
#  define BOOST_TEST_DYN_LINK
#endif

#define BOOST_TEST_MODULE plibraryloader_test

#include "plibsys.h"

#include <stdio.h>

#ifdef PLIBSYS_TESTS_STATIC
#  include <boost/test/included/unit_test.hpp>
#else
#  include <boost/test/unit_test.hpp>
#endif

extern "C" ppointer pmem_alloc (psize nbytes)
{
	P_UNUSED (nbytes);
	return (ppointer) NULL;
}

extern "C" ppointer pmem_realloc (ppointer block, psize nbytes)
{
	P_UNUSED (block);
	P_UNUSED (nbytes);
	return (ppointer) NULL;
}

extern "C" void pmem_free (ppointer block)
{
	P_UNUSED (block);
}

BOOST_AUTO_TEST_SUITE (BOOST_TEST_MODULE)

BOOST_AUTO_TEST_CASE (plibraryloader_nomem_test)
{
	p_libsys_init ();

	/* We assume that 2nd argument is ourself library path */
	BOOST_REQUIRE (boost::unit_test::framework::master_test_suite().argc == 2);

	/* Cleanup from previous run */
	p_file_remove ("." P_DIR_SEPARATOR "p_empty_file.txt", NULL);

	FILE *file = fopen ("." P_DIR_SEPARATOR "p_empty_file.txt", "w");
	BOOST_CHECK (file != NULL);
	BOOST_CHECK (fclose (file) == 0);

	PMemVTable vtable;

	vtable.free	= pmem_free;
	vtable.malloc	= pmem_alloc;
	vtable.realloc	= pmem_realloc;

	BOOST_CHECK (p_mem_set_vtable (&vtable) == TRUE);

#ifdef P_OS_WIN
	SetErrorMode (SEM_FAILCRITICALERRORS);
#endif

	BOOST_CHECK (p_library_loader_new ("." P_DIR_SEPARATOR "p_empty_file.txt") == NULL);
	BOOST_CHECK (p_library_loader_new (boost::unit_test::framework::master_test_suite().argv[1]) == NULL);

#ifdef P_OS_WIN
	SetErrorMode (0);
#endif

	vtable.malloc	= (ppointer (*)(psize)) malloc;
	vtable.realloc	= (ppointer (*)(ppointer, psize)) realloc;
	vtable.free	= (void (*)(ppointer)) free;

	BOOST_CHECK (p_mem_set_vtable (&vtable) == TRUE);

	BOOST_CHECK (p_file_remove ("." P_DIR_SEPARATOR "p_empty_file.txt", NULL) == TRUE);

	p_libsys_shutdown ();
}

BOOST_AUTO_TEST_CASE (plibraryloader_general_test)
{
	PLibraryLoader	*loader;
	pchar		*err_msg;
	void		(*shutdown_func) (void);

	p_libsys_init ();

	/* We assume that 2nd argument is ourself library path */
	BOOST_REQUIRE (boost::unit_test::framework::master_test_suite().argc == 2);

	/* Invalid usage */
	BOOST_CHECK (p_library_loader_new (NULL) == NULL);
	BOOST_CHECK (p_library_loader_new ("./unexistent_file.nofile") == NULL);
	BOOST_CHECK (p_library_loader_get_symbol (NULL, NULL) == NULL);
	BOOST_CHECK (p_library_loader_get_symbol (NULL, "unexistent_symbol") == NULL);

	p_library_loader_free (NULL);

	/* General tests */
	err_msg = p_library_loader_get_last_error ();
	p_free (err_msg);

	loader = p_library_loader_new (boost::unit_test::framework::master_test_suite().argv[1]);
	BOOST_REQUIRE (loader != NULL);

	BOOST_CHECK (p_library_loader_get_symbol (loader, "there_is_no_such_a_symbol") == (PFuncAddr) NULL);

	err_msg = p_library_loader_get_last_error ();
	BOOST_CHECK (err_msg != NULL);
	p_free (err_msg);

	shutdown_func = (void (*) (void)) p_library_loader_get_symbol (loader, "p_libsys_shutdown");

	if (shutdown_func == NULL)
		shutdown_func = (void (*) (void)) p_library_loader_get_symbol (loader, "_p_libsys_shutdown");

	BOOST_REQUIRE (shutdown_func != NULL);

	err_msg = p_library_loader_get_last_error ();
	p_free (err_msg);

	p_library_loader_free (loader);

	/* We have already loaded reference to ourself library, it's OK */
	shutdown_func ();
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#pragma once
#include <libunittest/all.hpp>
#include <densitas/all.hpp>
#include <armadillo>
using namespace unittest::assertions;

using vector_t = arma::vec;

using matrix_t = arma::mat;

struct mock_model {

    vector_t prediction;
    vector_t train_y;
    matrix_t train_X;

    mock_model()
        : prediction(), train_y(), train_X()
    {}

    void train(matrix_t& X, vector_t& y)
    {
        train_y = y;
        train_X = X;
    }

    vector_t predict_proba(matrix_t&) const
    {
        return prediction;
    }

};

const int no = densitas::model_adapter::no<mock_model>();

const int yes = densitas::model_adapter::yes<mock_model>();

const double dno = static_cast<double>(no);

const double dyes = static_cast<double>(yes);

namespace densitas {
namespace matrix_adapter {

template<>
inline
std::size_t n_rows(const matrix_t& matrix)
{
    return matrix.n_rows;
}

template<>
inline
std::size_t n_columns(const matrix_t& matrix)
{
    return matrix.n_cols;
}

} // matrix_adapter

namespace vector_adapter {

template<>
inline
std::size_t n_elements(const vector_t& vector)
{
    return vector.n_elem;
}

} // vector_adapter
} // densitas

namespace unittest {
namespace assertions {

template<typename... Args>
void
assert_equal_containers(const matrix_t& expected,
                        const matrix_t& actual,
                        const Args&... message)
{
    assert_equal(expected.n_rows, actual.n_rows, "n_rows don't match! ", message...);
    assert_equal(expected.n_cols, actual.n_cols, "n_cols don't match! ", message...);
    for (std::size_t i=0; i<expected.n_rows; ++i) {
        if (!unittest::core::is_containers_equal(vector_t(expected.row(i).t()), vector_t(actual.row(i).t()))) {
            const std::string text = "matrices are not equal";
            unittest::fail(UNITTEST_FUNC, text, message...);
        }
    }
}

template<typename... Args>
void
assert_approx_equal_containers(const matrix_t& expected,
                               const matrix_t& actual,
                               const double eps,
                               const Args&... message)
{
    assert_equal(expected.n_rows, actual.n_rows, "n_rows don't match! ", message...);
    assert_equal(expected.n_cols, actual.n_cols, "n_cols don't match! ", message...);
    for (std::size_t i=0; i<expected.n_rows; ++i) {
        if (!unittest::core::is_containers_approx_equal(vector_t(expected.row(i).t()), vector_t(actual.row(i).t()), eps)) {
            const std::string text = "matrices are not approx. equal";
            unittest::fail(UNITTEST_FUNC, text, message...);
        }
    }
}

} // unittest
} // assertions
<commit_msg>use typedef instead of using for gcc4.6 support<commit_after>#pragma once
#include <libunittest/all.hpp>
#include <densitas/all.hpp>
#include <armadillo>
using namespace unittest::assertions;

typedef arma::vec vector_t;

typedef arma::mat matrix_t;

struct mock_model {

    vector_t prediction;
    vector_t train_y;
    matrix_t train_X;

    mock_model()
        : prediction(), train_y(), train_X()
    {}

    void train(matrix_t& X, vector_t& y)
    {
        train_y = y;
        train_X = X;
    }

    vector_t predict_proba(matrix_t&) const
    {
        return prediction;
    }

};

const int no = densitas::model_adapter::no<mock_model>();

const int yes = densitas::model_adapter::yes<mock_model>();

const double dno = static_cast<double>(no);

const double dyes = static_cast<double>(yes);

namespace densitas {
namespace matrix_adapter {

template<>
inline
std::size_t n_rows(const matrix_t& matrix)
{
    return matrix.n_rows;
}

template<>
inline
std::size_t n_columns(const matrix_t& matrix)
{
    return matrix.n_cols;
}

} // matrix_adapter

namespace vector_adapter {

template<>
inline
std::size_t n_elements(const vector_t& vector)
{
    return vector.n_elem;
}

} // vector_adapter
} // densitas

namespace unittest {
namespace assertions {

template<typename... Args>
void
assert_equal_containers(const matrix_t& expected,
                        const matrix_t& actual,
                        const Args&... message)
{
    assert_equal(expected.n_rows, actual.n_rows, "n_rows don't match! ", message...);
    assert_equal(expected.n_cols, actual.n_cols, "n_cols don't match! ", message...);
    for (std::size_t i=0; i<expected.n_rows; ++i) {
        if (!unittest::core::is_containers_equal(vector_t(expected.row(i).t()), vector_t(actual.row(i).t()))) {
            const std::string text = "matrices are not equal";
            unittest::fail(UNITTEST_FUNC, text, message...);
        }
    }
}

template<typename... Args>
void
assert_approx_equal_containers(const matrix_t& expected,
                               const matrix_t& actual,
                               const double eps,
                               const Args&... message)
{
    assert_equal(expected.n_rows, actual.n_rows, "n_rows don't match! ", message...);
    assert_equal(expected.n_cols, actual.n_cols, "n_cols don't match! ", message...);
    for (std::size_t i=0; i<expected.n_rows; ++i) {
        if (!unittest::core::is_containers_approx_equal(vector_t(expected.row(i).t()), vector_t(actual.row(i).t()), eps)) {
            const std::string text = "matrices are not approx. equal";
            unittest::fail(UNITTEST_FUNC, text, message...);
        }
    }
}

} // unittest
} // assertions
<|endoftext|>


<commit_before>

#ifndef EGE_PRIVATE_GRAPHIC_GEOMETRY_MATRIX_HXX
#define EGE_PRIVATE_GRAPHIC_GEOMETRY_MATRIX_HXX

namespace ege_private
{
        namespace graphic
        {
                namespace geometry
                {
                        namespace matrix
                        {
                                static inline void multiply( float* out, const float* left, const float* right )
                                {
                                        out[  0 ] = ( left[  0 ] * right[  0 ] ) + ( left[  4 ] * right[  1 ] ) + ( left[  8 ] * right[  2 ] ) + ( left[ 12 ] * right[  3 ] );
                                        out[  4 ] = ( left[  0 ] * right[  4 ] ) + ( left[  4 ] * right[  5 ] ) + ( left[  8 ] * right[  6 ] ) + ( left[ 12 ] * right[  7 ] );
                                        out[  8 ] = ( left[  0 ] * right[  8 ] ) + ( left[  4 ] * right[  9 ] ) + ( left[  8 ] * right[ 10 ] ) + ( left[ 12 ] * right[ 11 ] );
                                        out[ 12 ] = ( left[  0 ] * right[ 12 ] ) + ( left[  4 ] * right[ 13 ] ) + ( left[  8 ] * right[ 14 ] ) + ( left[ 12 ] * right[ 15 ] );
                                        out[  1 ] = ( left[  1 ] * right[  0 ] ) + ( left[  5 ] * right[  1 ] ) + ( left[  9 ] * right[  2 ] ) + ( left[ 13 ] * right[  3 ] );
                                        out[  5 ] = ( left[  1 ] * right[  4 ] ) + ( left[  5 ] * right[  5 ] ) + ( left[  9 ] * right[  6 ] ) + ( left[ 13 ] * right[  7 ] );
                                        out[  9 ] = ( left[  1 ] * right[  8 ] ) + ( left[  5 ] * right[  9 ] ) + ( left[  9 ] * right[ 10 ] ) + ( left[ 13 ] * right[ 11 ] );
                                        out[ 13 ] = ( left[  1 ] * right[ 12 ] ) + ( left[  5 ] * right[ 13 ] ) + ( left[  9 ] * right[ 14 ] ) + ( left[ 13 ] * right[ 15 ] );
                                        out[  2 ] = ( left[  2 ] * right[  0 ] ) + ( left[  6 ] * right[  1 ] ) + ( left[ 10 ] * right[  2 ] ) + ( left[ 14 ] * right[  3 ] );
                                        out[  6 ] = ( left[  2 ] * right[  4 ] ) + ( left[  6 ] * right[  5 ] ) + ( left[ 10 ] * right[  6 ] ) + ( left[ 14 ] * right[  7 ] );
                                        out[ 10 ] = ( left[  2 ] * right[  8 ] ) + ( left[  6 ] * right[  9 ] ) + ( left[ 10 ] * right[ 10 ] ) + ( left[ 14 ] * right[ 11 ] );
                                        out[ 14 ] = ( left[  2 ] * right[ 12 ] ) + ( left[  6 ] * right[ 13 ] ) + ( left[ 10 ] * right[ 14 ] ) + ( left[ 14 ] * right[ 15 ] );
                                        out[  3 ] = ( left[  3 ] * right[  0 ] ) + ( left[  7 ] * right[  1 ] ) + ( left[ 11 ] * right[  2 ] ) + ( left[ 15 ] * right[  3 ] );
                                        out[  7 ] = ( left[  3 ] * right[  4 ] ) + ( left[  7 ] * right[  5 ] ) + ( left[ 11 ] * right[  6 ] ) + ( left[ 15 ] * right[  7 ] );
                                        out[ 11 ] = ( left[  3 ] * right[  8 ] ) + ( left[  7 ] * right[  9 ] ) + ( left[ 11 ] * right[ 10 ] ) + ( left[ 15 ] * right[ 11 ] );
                                        out[ 15 ] = ( left[  3 ] * right[ 12 ] ) + ( left[  7 ] * right[ 13 ] ) + ( left[ 11 ] * right[ 14 ] ) + ( left[ 15 ] * right[ 15 ] );
                                }
                        }
                }
        }
}

#endif
<commit_msg>added function to transform a matrix into identity<commit_after>

#ifndef EGE_PRIVATE_GRAPHIC_GEOMETRY_MATRIX_HXX
#define EGE_PRIVATE_GRAPHIC_GEOMETRY_MATRIX_HXX

namespace ege_private
{
        namespace graphic
        {
                namespace geometry
                {
                        namespace matrix
                        {
                                static inline void multiply( float* out, const float* left, const float* right )
                                {
                                        out[  0 ] = ( left[  0 ] * right[  0 ] ) + ( left[  4 ] * right[  1 ] ) + ( left[  8 ] * right[  2 ] ) + ( left[ 12 ] * right[  3 ] );
                                        out[  4 ] = ( left[  0 ] * right[  4 ] ) + ( left[  4 ] * right[  5 ] ) + ( left[  8 ] * right[  6 ] ) + ( left[ 12 ] * right[  7 ] );
                                        out[  8 ] = ( left[  0 ] * right[  8 ] ) + ( left[  4 ] * right[  9 ] ) + ( left[  8 ] * right[ 10 ] ) + ( left[ 12 ] * right[ 11 ] );
                                        out[ 12 ] = ( left[  0 ] * right[ 12 ] ) + ( left[  4 ] * right[ 13 ] ) + ( left[  8 ] * right[ 14 ] ) + ( left[ 12 ] * right[ 15 ] );
                                        out[  1 ] = ( left[  1 ] * right[  0 ] ) + ( left[  5 ] * right[  1 ] ) + ( left[  9 ] * right[  2 ] ) + ( left[ 13 ] * right[  3 ] );
                                        out[  5 ] = ( left[  1 ] * right[  4 ] ) + ( left[  5 ] * right[  5 ] ) + ( left[  9 ] * right[  6 ] ) + ( left[ 13 ] * right[  7 ] );
                                        out[  9 ] = ( left[  1 ] * right[  8 ] ) + ( left[  5 ] * right[  9 ] ) + ( left[  9 ] * right[ 10 ] ) + ( left[ 13 ] * right[ 11 ] );
                                        out[ 13 ] = ( left[  1 ] * right[ 12 ] ) + ( left[  5 ] * right[ 13 ] ) + ( left[  9 ] * right[ 14 ] ) + ( left[ 13 ] * right[ 15 ] );
                                        out[  2 ] = ( left[  2 ] * right[  0 ] ) + ( left[  6 ] * right[  1 ] ) + ( left[ 10 ] * right[  2 ] ) + ( left[ 14 ] * right[  3 ] );
                                        out[  6 ] = ( left[  2 ] * right[  4 ] ) + ( left[  6 ] * right[  5 ] ) + ( left[ 10 ] * right[  6 ] ) + ( left[ 14 ] * right[  7 ] );
                                        out[ 10 ] = ( left[  2 ] * right[  8 ] ) + ( left[  6 ] * right[  9 ] ) + ( left[ 10 ] * right[ 10 ] ) + ( left[ 14 ] * right[ 11 ] );
                                        out[ 14 ] = ( left[  2 ] * right[ 12 ] ) + ( left[  6 ] * right[ 13 ] ) + ( left[ 10 ] * right[ 14 ] ) + ( left[ 14 ] * right[ 15 ] );
                                        out[  3 ] = ( left[  3 ] * right[  0 ] ) + ( left[  7 ] * right[  1 ] ) + ( left[ 11 ] * right[  2 ] ) + ( left[ 15 ] * right[  3 ] );
                                        out[  7 ] = ( left[  3 ] * right[  4 ] ) + ( left[  7 ] * right[  5 ] ) + ( left[ 11 ] * right[  6 ] ) + ( left[ 15 ] * right[  7 ] );
                                        out[ 11 ] = ( left[  3 ] * right[  8 ] ) + ( left[  7 ] * right[  9 ] ) + ( left[ 11 ] * right[ 10 ] ) + ( left[ 15 ] * right[ 11 ] );
                                        out[ 15 ] = ( left[  3 ] * right[ 12 ] ) + ( left[  7 ] * right[ 13 ] ) + ( left[ 11 ] * right[ 14 ] ) + ( left[ 15 ] * right[ 15 ] );
                                }

                                static inline void identity( float* matrix )
                                {
                                        matrix[  0 ] = 1.0f;
                                        matrix[  1 ] = 0.0f;
                                        matrix[  2 ] = 0.0f;
                                        matrix[  3 ] = 0.0f;
                                        matrix[  4 ] = 0.0f;
                                        matrix[  5 ] = 1.0f;
                                        matrix[  6 ] = 0.0f;
                                        matrix[  7 ] = 0.0f;
                                        matrix[  8 ] = 0.0f;
                                        matrix[  9 ] = 0.0f;
                                        matrix[ 10 ] = 1.0f;
                                        matrix[ 11 ] = 0.0f;
                                        matrix[ 12 ] = 0.0f;
                                        matrix[ 13 ] = 0.0f;
                                        matrix[ 14 ] = 0.0f;
                                        matrix[ 15 ] = 1.0f;
                                }
                        }
                }
        }
}

#endif
<|endoftext|>


<commit_before>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009      Andrew Manson <g.real.ate@gmail.com>
//

#include "OsmBoundsGraphicsItem.h"

#include <QtCore/QDebug>

namespace Marble{

OsmBoundsGraphicsItem::OsmBoundsGraphicsItem() : GeoDataLineString()
{
}

OsmBoundsGraphicsItem::OsmBoundsGraphicsItem( GeoDataGeometry& other )
//        : GeoDataLineString( other )
{
}

void OsmBoundsGraphicsItem::paint( Geopainter* painter, ViewportParams * viewport,
                                   const QString &renderPos, GeoSceneLayer* layer )
{

    Q_UNUSED( renderPos )
    Q_UNUSED( layer )

    qDebug() << "Painting from OSMBounds";

}

}
<commit_msg>correct type name<commit_after>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009      Andrew Manson <g.real.ate@gmail.com>
//

#include "OsmBoundsGraphicsItem.h"

#include <QtCore/QDebug>

namespace Marble{

OsmBoundsGraphicsItem::OsmBoundsGraphicsItem() : GeoDataLineString()
{
}

OsmBoundsGraphicsItem::OsmBoundsGraphicsItem( GeoDataGeometry& other )
//        : GeoDataLineString( other )
{
}

void OsmBoundsGraphicsItem::paint( GeoPainter* painter, ViewportParams * viewport,
                                   const QString &renderPos, GeoSceneLayer* layer )
{

    Q_UNUSED( renderPos )
    Q_UNUSED( layer )

    qDebug() << "Painting from OSMBounds";

}

}
<|endoftext|>


<commit_before>#include "../JSON_Parser.hxx"

bool JSON_Parser::EndObject(rapidjson::SizeType memberCount)
{
  if(inside)
    {
      if(parsing_objective)
        {
          throw std::runtime_error(
            "Invalid input file.  Found an object end inside '"
            + objective_state.name + "'");
        }
      else if(parsing_normalization)
        {
          throw std::runtime_error(
            "Invalid input file.  Found an object end inside '"
            + normalization_state.name + "'");
        }
      else if(parsing_positive_matrices_with_prefactor)
        {
          positive_matrices_with_prefactor_state.json_end_object();
        }
      else
        {
          inside = false;
        }
    }
  else
    {
      throw std::runtime_error(
        "Invalid input file.  Ending an object outside of the SDP");
    }
  return true;
}
<commit_msg>Fix warning<commit_after>#include "../JSON_Parser.hxx"

bool JSON_Parser::EndObject(rapidjson::SizeType)
{
  if(inside)
    {
      if(parsing_objective)
        {
          throw std::runtime_error(
            "Invalid input file.  Found an object end inside '"
            + objective_state.name + "'");
        }
      else if(parsing_normalization)
        {
          throw std::runtime_error(
            "Invalid input file.  Found an object end inside '"
            + normalization_state.name + "'");
        }
      else if(parsing_positive_matrices_with_prefactor)
        {
          positive_matrices_with_prefactor_state.json_end_object();
        }
      else
        {
          inside = false;
        }
    }
  else
    {
      throw std::runtime_error(
        "Invalid input file.  Ending an object outside of the SDP");
    }
  return true;
}
<|endoftext|>


<commit_before>#ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__NORMAL_HPP__
#define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__NORMAL_HPP__

#include <stan/prob/constants.hpp>
#include <stan/math/error_handling.hpp>
#include <stan/prob/traits.hpp>

namespace stan {

  namespace prob {
    /**
     * The log of the normal density for the given y, mean, and
     * standard deviation.  The standard deviation must be greater
     * than 0.
     *
     * \f{eqnarray*}{
     y &\sim& \mbox{\sf{N}} (\mu, \sigma^2) \\
     \log (p (y \,|\, \mu, \sigma) ) &=& \log \left( \frac{1}{\sqrt{2 \pi} \sigma} \exp \left( - \frac{1}{2 \sigma^2} (y - \mu)^2 \right) \right) \\
     &=& \log (1) - \frac{1}{2}\log (2 \pi) - \log (\sigma) - \frac{(y - \mu)^2}{2 \sigma^2}
     \f}
     *
     * Errors are configured by policy.  All variables must be finite
     * and the scale must be strictly greater than zero.
     *
     * @param y A scalar variate.
     * @param mu The location of the normal distribution.
     * @param sigma The scale of the normal distribution.
     * @return The log of the normal density of the specified arguments.
     * @tparam propto Set to true if only calculated up
     * to a proportion.
     * @tparam T_y Type of scalar.
     * @tparam T_loc Type of location.
     * @tparam T_scale Type of scale.
     * @tparam Policy Error-handling policy.
     */
    template <bool propto,
              typename T_y, typename T_loc, typename T_scale,
              class Policy>
    typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
    normal_log(const T_y& y, const T_loc& mu, const T_scale& sigma,
               const Policy&) {
      static const char* function = "stan::prob::normal_log<%1%>(%1%)";

      using stan::math::check_positive;
      using stan::math::check_finite;
      using stan::math::check_not_nan;
      using boost::math::tools::promote_args;

      typename promote_args<T_y,T_loc,T_scale>::type lp(0.0);
      if (!check_not_nan(function, y, "Random variate y", &lp, Policy()))
        return lp;
      if (!check_finite(function, mu, "Location parameter, mu,",
                        &lp, Policy()))
        return lp;
      if (!check_not_nan(function, sigma, "Scale parameter, sigma,",
                         &lp, Policy()))
        return lp;
      if (!check_positive(function, sigma, "Scale parameter, sigma,",
                          &lp, Policy()))
        return lp;

      using stan::math::square;

      if (include_summand<propto,T_y,T_loc,T_scale>::value)
        lp -= square(y - mu) / (2.0 * square(sigma));

      if (include_summand<propto,T_scale>::value)
        lp -= log(sigma);

      if (include_summand<propto>::value)
        lp += NEG_LOG_SQRT_TWO_PI;

      return lp;
    }

    template <bool propto,
              typename T_y, typename T_loc, typename T_scale>
    inline
    typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
    normal_log(const T_y& y, const T_loc& mu, const T_scale& sigma) {
      return normal_log<propto>(y,mu,sigma,stan::math::default_policy());
    }

    template <typename T_y, typename T_loc, typename T_scale,
              class Policy>
    inline
    typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
    normal_log(const T_y& y, const T_loc& mu, const T_scale& sigma,
               const Policy&) {
      return normal_log<false>(y,mu,sigma,Policy());
    }

    template <typename T_y, typename T_loc, typename T_scale>
    inline
    typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
    normal_log(const T_y& y, const T_loc& mu, const T_scale& sigma) {
      return normal_log<false>(y,mu,sigma,stan::math::default_policy());
    }

    /**
     * Calculates the normal cumulative distribution function for the given
     * variate, location, and scale.
     *
     * \f$\Phi(x) = \frac{1}{\sqrt{2 \pi}} \int_{-\inf}^x e^{-t^2/2} dt\f$.
     *
     * Errors are configured by policy.  All variables must be finite
     * and the scale must be strictly greater than zero.
     *
     * @param y A scalar variate.
     * @param mu The location of the normal distribution.
     * @param sigma The scale of the normal distriubtion
     * @return The unit normal cdf evaluated at the specified arguments.
     * @tparam propto Set to true if only calculated up to a
     * proportion.
     * @tparam T_y Type of y.
     * @tparam T_loc Type of mean parameter.
     * @tparam T_scale Type of standard deviation paramater.
     * @tparam Policy Error-handling policy.
     */
    template <typename T_y, typename T_loc, typename T_scale,
              class Policy>
    typename boost::math::tools::promote_args<T_y, T_loc, T_scale>::type
    normal_p(const T_y& y, const T_loc& mu, const T_scale& sigma,
             const Policy&) {
      static const char* function = "stan::prob::normal_p(%1%)";

      using stan::math::check_positive;
      using stan::math::check_finite;
      using stan::math::check_not_nan;

      using boost::math::tools::promote_args;
      typename promote_args<T_y, T_loc, T_scale>::type lp;
      if (!check_not_nan(function, y, "Random variate y", &lp, Policy()))
        return lp;
      if (!check_finite(function, mu, "Location parameter, mu,", &lp, Policy()))
        return lp;
      if (!check_not_nan(function, sigma, "Scale parameter, sigma,",
                         &lp, Policy()))
        return lp;
      if (!check_positive(function, sigma, "Scale parameter, sigma,",
                          &lp, Policy()))
        return lp;

      return 0.5 * erfc(-(y - mu)/(sigma * SQRT_2));
    }

    template <typename T_y, typename T_loc, typename T_scale>
    inline
    typename boost::math::tools::promote_args<T_y, T_loc, T_scale>::type
    normal_p(const T_y& y, const T_loc& mu, const T_scale& sigma) {
      return normal_p(y,mu,sigma,stan::math::default_policy());
    }

    /**
     * The log of the normal density for the specified sequence of
     * scalars given the specified mean and deviation.  If the
     * sequence of values is of length 0, the result is 0.0.
     *
     *
The result log probability is defined to be the sum of the
     * log probabilities for each observation.  Hence if the sequence
     * is of length 0, the log probability is 0.0.
     *
     * @param y Sequence of scalars.
     * @param mu Location parameter for the normal distribution.
     * @param sigma Scale parameter for the normal distribution.
     * @return The log of the product of the densities.
     * @throw std::domain_error if the scale is not positive.
     * @tparam T_y Underlying type of scalar in sequence.
     * @tparam T_loc Type of location parameter.
     */
    template <bool propto,
              typename T_y, typename T_loc, typename T_scale,
              class Policy>
    typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
    normal_log(const std::vector<T_y>& y,
               const T_loc& mu,
               const T_scale& sigma,
               const Policy&) {
      static const char* function = "stan::prob::normal_log<%1%>(%1%)";

      using stan::math::check_positive;
      using stan::math::check_finite;
      using stan::math::check_not_nan;

      using boost::math::tools::promote_args;
      typename promote_args<T_y,T_loc,T_scale>::type lp;
      if (!check_not_nan(function, y, "Random variate y", &lp, Policy()))
        return lp;
      if (!check_finite(function, mu, "Location parameter, mu,", &lp, Policy()))
        return lp;
      if (!check_not_nan(function, sigma, "Scale parameter, sigma,",
                         &lp, Policy()))
        return lp;
      if (!check_positive(function, sigma, "Scale parameter, sigma,",
                          &lp, Policy()))
        return lp;

      if (y.size() == 0)
        return 0.0;

      using stan::math::square;
      using stan::math::multiply_log;

      lp = 0.0;
      if (include_summand<propto,T_y,T_loc,T_scale>::value) {
        for (unsigned int n = 0; n < y.size(); ++n)
          lp -= square(y[n] - mu);
        lp /= 2.0 * square(sigma);
      }
      if (include_summand<propto,T_scale>::value)
        lp -= multiply_log(y.size(),sigma);
      if (include_summand<propto>::value)
        lp += y.size() * NEG_LOG_SQRT_TWO_PI;

      return lp;
    }

    template <bool propto,
              typename T_y, typename T_loc, typename T_scale>
    inline
    typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
    normal_log(const std::vector<T_y>& y,
               const T_loc& mu,
               const T_scale& sigma) {
      return normal_log<propto>(y,mu,sigma,stan::math::default_policy());
    }

    template <typename T_y, typename T_loc, typename T_scale,
              class Policy>
    inline
    typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
    normal_log(const std::vector<T_y>& y,
               const T_loc& mu,
               const T_scale& sigma,
               const Policy&) {
      return normal_log<false>(y,mu,sigma,Policy());
    }

    template <typename T_y, typename T_loc, typename T_scale>
    inline
    typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
    normal_log(const std::vector<T_y>& y,
               const T_loc& mu,
               const T_scale& sigma) {
      return normal_log<false>(y,mu,sigma,stan::math::default_policy());
    }

  }
}
#endif
<commit_msg>sorted imports<commit_after>#ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__NORMAL_HPP__
#define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__NORMAL_HPP__

#include <stan/math/error_handling.hpp>
#include <stan/prob/constants.hpp>
#include <stan/prob/traits.hpp>

namespace stan {

  namespace prob {
    /**
     * The log of the normal density for the given y, mean, and
     * standard deviation.  The standard deviation must be greater
     * than 0.
     *
     * \f{eqnarray*}{
     y &\sim& \mbox{\sf{N}} (\mu, \sigma^2) \\
     \log (p (y \,|\, \mu, \sigma) ) &=& \log \left( \frac{1}{\sqrt{2 \pi} \sigma} \exp \left( - \frac{1}{2 \sigma^2} (y - \mu)^2 \right) \right) \\
     &=& \log (1) - \frac{1}{2}\log (2 \pi) - \log (\sigma) - \frac{(y - \mu)^2}{2 \sigma^2}
     \f}
     *
     * Errors are configured by policy.  All variables must be finite
     * and the scale must be strictly greater than zero.
     *
     * @param y A scalar variate.
     * @param mu The location of the normal distribution.
     * @param sigma The scale of the normal distribution.
     * @return The log of the normal density of the specified arguments.
     * @tparam propto Set to true if only calculated up
     * to a proportion.
     * @tparam T_y Type of scalar.
     * @tparam T_loc Type of location.
     * @tparam T_scale Type of scale.
     * @tparam Policy Error-handling policy.
     */
    template <bool propto,
              typename T_y, typename T_loc, typename T_scale,
              class Policy>
    typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
    normal_log(const T_y& y, const T_loc& mu, const T_scale& sigma,
               const Policy&) {
      static const char* function = "stan::prob::normal_log<%1%>(%1%)";

      using stan::math::check_positive;
      using stan::math::check_finite;
      using stan::math::check_not_nan;
      using boost::math::tools::promote_args;

      typename promote_args<T_y,T_loc,T_scale>::type lp(0.0);
      if (!check_not_nan(function, y, "Random variate y", &lp, Policy()))
        return lp;
      if (!check_finite(function, mu, "Location parameter, mu,",
                        &lp, Policy()))
        return lp;
      if (!check_not_nan(function, sigma, "Scale parameter, sigma,",
                         &lp, Policy()))
        return lp;
      if (!check_positive(function, sigma, "Scale parameter, sigma,",
                          &lp, Policy()))
        return lp;

      using stan::math::square;

      if (include_summand<propto,T_y,T_loc,T_scale>::value)
        lp -= square(y - mu) / (2.0 * square(sigma));

      if (include_summand<propto,T_scale>::value)
        lp -= log(sigma);

      if (include_summand<propto>::value)
        lp += NEG_LOG_SQRT_TWO_PI;

      return lp;
    }

    template <bool propto,
              typename T_y, typename T_loc, typename T_scale>
    inline
    typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
    normal_log(const T_y& y, const T_loc& mu, const T_scale& sigma) {
      return normal_log<propto>(y,mu,sigma,stan::math::default_policy());
    }

    template <typename T_y, typename T_loc, typename T_scale,
              class Policy>
    inline
    typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
    normal_log(const T_y& y, const T_loc& mu, const T_scale& sigma,
               const Policy&) {
      return normal_log<false>(y,mu,sigma,Policy());
    }

    template <typename T_y, typename T_loc, typename T_scale>
    inline
    typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
    normal_log(const T_y& y, const T_loc& mu, const T_scale& sigma) {
      return normal_log<false>(y,mu,sigma,stan::math::default_policy());
    }

    /**
     * Calculates the normal cumulative distribution function for the given
     * variate, location, and scale.
     *
     * \f$\Phi(x) = \frac{1}{\sqrt{2 \pi}} \int_{-\inf}^x e^{-t^2/2} dt\f$.
     *
     * Errors are configured by policy.  All variables must be finite
     * and the scale must be strictly greater than zero.
     *
     * @param y A scalar variate.
     * @param mu The location of the normal distribution.
     * @param sigma The scale of the normal distriubtion
     * @return The unit normal cdf evaluated at the specified arguments.
     * @tparam propto Set to true if only calculated up to a
     * proportion.
     * @tparam T_y Type of y.
     * @tparam T_loc Type of mean parameter.
     * @tparam T_scale Type of standard deviation paramater.
     * @tparam Policy Error-handling policy.
     */
    template <typename T_y, typename T_loc, typename T_scale,
              class Policy>
    typename boost::math::tools::promote_args<T_y, T_loc, T_scale>::type
    normal_p(const T_y& y, const T_loc& mu, const T_scale& sigma,
             const Policy&) {
      static const char* function = "stan::prob::normal_p(%1%)";

      using stan::math::check_positive;
      using stan::math::check_finite;
      using stan::math::check_not_nan;

      using boost::math::tools::promote_args;
      typename promote_args<T_y, T_loc, T_scale>::type lp;
      if (!check_not_nan(function, y, "Random variate y", &lp, Policy()))
        return lp;
      if (!check_finite(function, mu, "Location parameter, mu,", &lp, Policy()))
        return lp;
      if (!check_not_nan(function, sigma, "Scale parameter, sigma,",
                         &lp, Policy()))
        return lp;
      if (!check_positive(function, sigma, "Scale parameter, sigma,",
                          &lp, Policy()))
        return lp;

      return 0.5 * erfc(-(y - mu)/(sigma * SQRT_2));
    }

    template <typename T_y, typename T_loc, typename T_scale>
    inline
    typename boost::math::tools::promote_args<T_y, T_loc, T_scale>::type
    normal_p(const T_y& y, const T_loc& mu, const T_scale& sigma) {
      return normal_p(y,mu,sigma,stan::math::default_policy());
    }

    /**
     * The log of the normal density for the specified sequence of
     * scalars given the specified mean and deviation.  If the
     * sequence of values is of length 0, the result is 0.0.
     *
     *
The result log probability is defined to be the sum of the
     * log probabilities for each observation.  Hence if the sequence
     * is of length 0, the log probability is 0.0.
     *
     * @param y Sequence of scalars.
     * @param mu Location parameter for the normal distribution.
     * @param sigma Scale parameter for the normal distribution.
     * @return The log of the product of the densities.
     * @throw std::domain_error if the scale is not positive.
     * @tparam T_y Underlying type of scalar in sequence.
     * @tparam T_loc Type of location parameter.
     */
    template <bool propto,
              typename T_y, typename T_loc, typename T_scale,
              class Policy>
    typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
    normal_log(const std::vector<T_y>& y,
               const T_loc& mu,
               const T_scale& sigma,
               const Policy&) {
      static const char* function = "stan::prob::normal_log<%1%>(%1%)";

      using stan::math::check_positive;
      using stan::math::check_finite;
      using stan::math::check_not_nan;

      using boost::math::tools::promote_args;
      typename promote_args<T_y,T_loc,T_scale>::type lp;
      if (!check_not_nan(function, y, "Random variate y", &lp, Policy()))
        return lp;
      if (!check_finite(function, mu, "Location parameter, mu,", &lp, Policy()))
        return lp;
      if (!check_not_nan(function, sigma, "Scale parameter, sigma,",
                         &lp, Policy()))
        return lp;
      if (!check_positive(function, sigma, "Scale parameter, sigma,",
                          &lp, Policy()))
        return lp;

      if (y.size() == 0)
        return 0.0;

      using stan::math::square;
      using stan::math::multiply_log;

      lp = 0.0;
      if (include_summand<propto,T_y,T_loc,T_scale>::value) {
        for (unsigned int n = 0; n < y.size(); ++n)
          lp -= square(y[n] - mu);
        lp /= 2.0 * square(sigma);
      }
      if (include_summand<propto,T_scale>::value)
        lp -= multiply_log(y.size(),sigma);
      if (include_summand<propto>::value)
        lp += y.size() * NEG_LOG_SQRT_TWO_PI;

      return lp;
    }

    template <bool propto,
              typename T_y, typename T_loc, typename T_scale>
    inline
    typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
    normal_log(const std::vector<T_y>& y,
               const T_loc& mu,
               const T_scale& sigma) {
      return normal_log<propto>(y,mu,sigma,stan::math::default_policy());
    }

    template <typename T_y, typename T_loc, typename T_scale,
              class Policy>
    inline
    typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
    normal_log(const std::vector<T_y>& y,
               const T_loc& mu,
               const T_scale& sigma,
               const Policy&) {
      return normal_log<false>(y,mu,sigma,Policy());
    }

    template <typename T_y, typename T_loc, typename T_scale>
    inline
    typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
    normal_log(const std::vector<T_y>& y,
               const T_loc& mu,
               const T_scale& sigma) {
      return normal_log<false>(y,mu,sigma,stan::math::default_policy());
    }

  }
}
#endif
<|endoftext|>