<commit_before>/*
 * Copyright 2004 The Apache Software Foundation.
 *
 * 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
 * imitations under the License.
 */

/*
 * XSEC
 *
 * XSECSOAPRequestorSimple := (Very) Basic implementation of a SOAP
 *                         HTTP wrapper for testing the client code.
 *
 *
 * $Id$
 *
 */

#include "XSECSOAPRequestorSimple.hpp"

#include <xsec/framework/XSECError.hpp>
#include <xsec/utils/XSECSafeBuffer.hpp>
#include <xsec/utils/XSECDOMUtils.hpp>
#include <xsec/xkms/XKMSConstants.hpp>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <xercesc/dom/DOM.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/framework/XMLFormatter.hpp>
#include <xercesc/framework/MemBufFormatTarget.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLNetAccessor.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLExceptMsgs.hpp>
#include <xercesc/util/Janitor.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>

XERCES_CPP_NAMESPACE_USE

// --------------------------------------------------------------------------------
//           Strings for constructing SOAP envelopes
// --------------------------------------------------------------------------------

static XMLCh s_prefix[] = {

	chLatin_e,
	chLatin_n,
	chLatin_v,
	chNull
};

static XMLCh s_Envelope[] = {

	chLatin_E,
	chLatin_n,
	chLatin_v,
	chLatin_e,
	chLatin_l,
	chLatin_o,
	chLatin_p,
	chLatin_e,
	chNull
};

static XMLCh s_Body[] = {

	chLatin_B,
	chLatin_o,
	chLatin_d,
	chLatin_y,
	chNull
};

// --------------------------------------------------------------------------------
//           Constructors and Destructors
// --------------------------------------------------------------------------------

/* NOTE: This is initialised via the platform specific code */

XSECSOAPRequestorSimple::~XSECSOAPRequestorSimple() {
}

// --------------------------------------------------------------------------------
//           Wrap and serialise the request message
// --------------------------------------------------------------------------------

char * XSECSOAPRequestorSimple::wrapAndSerialise(DOMDocument * request) {

	// Create a new document to wrap the request in

	XMLCh tempStr[100];
	XMLString::transcode("Core", tempStr, 99);
	DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(tempStr);

	safeBuffer str;

	makeQName(str, s_prefix, s_Envelope);

	DOMDocument *doc = impl->createDocument(
		XKMSConstants::s_unicodeStrURISOAP11,
				str.rawXMLChBuffer(),
				NULL);// DOMDocumentType());  // document type object (DTD).

	DOMElement *rootElem = doc->getDocumentElement();

	makeQName(str, s_prefix, s_Body);
	DOMElement *body = doc->createElementNS(
			XKMSConstants::s_unicodeStrURISOAP11,
			str.rawXMLChBuffer());

	rootElem->appendChild(body);

	// Now replicate the request into the document
	DOMElement * reqElement = (DOMElement *) doc->importNode(request->getDocumentElement(), true);
	body->appendChild(reqElement);

	// OK - Now we have the SOAP request as a document, we serialise to a string buffer
	// and return

	DOMWriter         *theSerializer = ((DOMImplementationLS*)impl)->createDOMWriter();

	theSerializer->setEncoding(MAKE_UNICODE_STRING("UTF-8"));
	if (theSerializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, false))
		theSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, false);

	MemBufFormatTarget *formatTarget = new MemBufFormatTarget;
	theSerializer->writeNode(formatTarget, *doc);

	// Now replicate the buffer
	char * ret = XMLString::replicate((const char *) formatTarget->getRawBuffer());

	delete theSerializer;
	delete formatTarget;

	doc->release();

	return ret;
}

// --------------------------------------------------------------------------------
//           UnWrap and de-serialise the response message
// --------------------------------------------------------------------------------

DOMDocument * XSECSOAPRequestorSimple::parseAndUnwrap(const char * buf, unsigned int len) {

	XercesDOMParser * parser = new XercesDOMParser;
	Janitor<XercesDOMParser> j_parser(parser);

	parser->setDoNamespaces(true);
	parser->setCreateEntityReferenceNodes(true);
	parser->setDoSchema(true);

	// Create an input source

	MemBufInputSource* memIS = new MemBufInputSource ((const XMLByte*) buf, len, "XSECMem");
	Janitor<MemBufInputSource> j_memIS(memIS);

	int errorCount = 0;

	parser->parse(*memIS);
    errorCount = parser->getErrorCount();
    if (errorCount > 0)
		throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error parsing SOAP response message");

    DOMDocument * responseDoc = parser->getDocument();

	// Now create a new document for the Response message
	XMLCh tempStr[100];
	XMLString::transcode("Core", tempStr, 99);
	DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(tempStr);

	DOMDocument * retDoc = impl->createDocument();

	// Find the base of the response

	DOMNode * e = responseDoc->getDocumentElement();

	e = e->getFirstChild();

	while (e != NULL && (e->getNodeType() != DOMNode::ELEMENT_NODE || !strEquals(e->getLocalName(), "Body")))
		e = e->getNextSibling();

	if (e == NULL)
		throw XSECException(XSECException::HTTPURIInputStreamError,
							"Could not find SOAP body");

	e = findFirstChildOfType(e, DOMNode::ELEMENT_NODE);

	if (e == NULL)
		throw XSECException(XSECException::HTTPURIInputStreamError,
							"Could not find message within SOAP body");

	retDoc->appendChild(retDoc->importNode(e, true));

	return retDoc;

}
<commit_msg>Implement checking of SOAP faults<commit_after>/*
 * Copyright 2004 The Apache Software Foundation.
 *
 * 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
 * imitations under the License.
 */

/*
 * XSEC
 *
 * XSECSOAPRequestorSimple := (Very) Basic implementation of a SOAP
 *                         HTTP wrapper for testing the client code.
 *
 *
 * $Id$
 *
 */

#include "XSECSOAPRequestorSimple.hpp"

#include <xsec/framework/XSECError.hpp>
#include <xsec/utils/XSECSafeBuffer.hpp>
#include <xsec/utils/XSECDOMUtils.hpp>
#include <xsec/xkms/XKMSConstants.hpp>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <xercesc/dom/DOM.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/framework/XMLFormatter.hpp>
#include <xercesc/framework/MemBufFormatTarget.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLNetAccessor.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLExceptMsgs.hpp>
#include <xercesc/util/Janitor.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>

XERCES_CPP_NAMESPACE_USE

// --------------------------------------------------------------------------------
//           Strings for constructing SOAP envelopes
// --------------------------------------------------------------------------------

static XMLCh s_prefix[] = {

	chLatin_e,
	chLatin_n,
	chLatin_v,
	chNull
};

static XMLCh s_Envelope[] = {

	chLatin_E,
	chLatin_n,
	chLatin_v,
	chLatin_e,
	chLatin_l,
	chLatin_o,
	chLatin_p,
	chLatin_e,
	chNull
};

static XMLCh s_Body[] = {

	chLatin_B,
	chLatin_o,
	chLatin_d,
	chLatin_y,
	chNull
};

// --------------------------------------------------------------------------------
//           Constructors and Destructors
// --------------------------------------------------------------------------------

/* NOTE: This is initialised via the platform specific code */

XSECSOAPRequestorSimple::~XSECSOAPRequestorSimple() {
}

// --------------------------------------------------------------------------------
//           Wrap and serialise the request message
// --------------------------------------------------------------------------------

char * XSECSOAPRequestorSimple::wrapAndSerialise(DOMDocument * request) {

	// Create a new document to wrap the request in

	XMLCh tempStr[100];
	XMLString::transcode("Core", tempStr, 99);
	DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(tempStr);

	safeBuffer str;

	makeQName(str, s_prefix, s_Envelope);

	DOMDocument *doc = impl->createDocument(
		XKMSConstants::s_unicodeStrURISOAP11,
				str.rawXMLChBuffer(),
				NULL);// DOMDocumentType());  // document type object (DTD).

	DOMElement *rootElem = doc->getDocumentElement();

	makeQName(str, s_prefix, s_Body);
	DOMElement *body = doc->createElementNS(
			XKMSConstants::s_unicodeStrURISOAP11,
			str.rawXMLChBuffer());

	rootElem->appendChild(body);

	// Now replicate the request into the document
	DOMElement * reqElement = (DOMElement *) doc->importNode(request->getDocumentElement(), true);
	body->appendChild(reqElement);

	// OK - Now we have the SOAP request as a document, we serialise to a string buffer
	// and return

	DOMWriter         *theSerializer = ((DOMImplementationLS*)impl)->createDOMWriter();

	theSerializer->setEncoding(MAKE_UNICODE_STRING("UTF-8"));
	if (theSerializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, false))
		theSerializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, false);

	MemBufFormatTarget *formatTarget = new MemBufFormatTarget;
	theSerializer->writeNode(formatTarget, *doc);

	// Now replicate the buffer
	char * ret = XMLString::replicate((const char *) formatTarget->getRawBuffer());

	delete theSerializer;
	delete formatTarget;

	doc->release();

	return ret;
}

// --------------------------------------------------------------------------------
//           UnWrap and de-serialise the response message
// --------------------------------------------------------------------------------

DOMDocument * XSECSOAPRequestorSimple::parseAndUnwrap(const char * buf, unsigned int len) {

	XercesDOMParser * parser = new XercesDOMParser;
	Janitor<XercesDOMParser> j_parser(parser);

	parser->setDoNamespaces(true);
	parser->setCreateEntityReferenceNodes(true);
	parser->setDoSchema(true);

	// Create an input source

	MemBufInputSource* memIS = new MemBufInputSource ((const XMLByte*) buf, len, "XSECMem");
	Janitor<MemBufInputSource> j_memIS(memIS);

	int errorCount = 0;

	parser->parse(*memIS);
    errorCount = parser->getErrorCount();
    if (errorCount > 0)
		throw XSECException(XSECException::HTTPURIInputStreamError,
							"Error parsing SOAP response message");

    DOMDocument * responseDoc = parser->getDocument();

	// Now create a new document for the Response message
	XMLCh tempStr[100];
	XMLString::transcode("Core", tempStr, 99);
	DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(tempStr);

	DOMDocument * retDoc = impl->createDocument();

	// Find the base of the response

	DOMNode * e = responseDoc->getDocumentElement();

	e = e->getFirstChild();

	while (e != NULL && (e->getNodeType() != DOMNode::ELEMENT_NODE || !strEquals(e->getLocalName(), "Body")))
		e = e->getNextSibling();

	if (e == NULL)
		throw XSECException(XSECException::HTTPURIInputStreamError,
							"Could not find SOAP body");

	e = findFirstChildOfType(e, DOMNode::ELEMENT_NODE);

	if (e == NULL)
		throw XSECException(XSECException::HTTPURIInputStreamError,
							"Could not find message within SOAP body");

	/* See if this is a soap fault */
	if (strEquals(e->getLocalName(), "Fault")) {

		// Something has gone wrong somewhere!
		safeBuffer sb;
		sb.sbTranscodeIn("SOAP Fault : ");

		// Find the fault code

		e = findFirstElementChild(e);
		while (e != NULL && !strEquals(e->getLocalName(), "Code"))
			e = findNextElementChild(e);

		if (e != NULL) {
			DOMNode * c = findFirstElementChild(e);
			while (c != NULL && !strEquals(c->getLocalName(), "Value"))
				c = findNextElementChild(c);
			if (c != NULL) {
				DOMNode * t = findFirstChildOfType(c, DOMNode::TEXT_NODE);
				if (t != NULL) {
					sb.sbXMLChCat(t->getNodeValue());
					sb.sbXMLChCat(" : ");
				}
			}
		}

		// Find the reason
		while (e != NULL && !strEquals(e->getLocalName(), "Reason"))
			e = findNextElementChild(e);

		if (e != NULL) {
			DOMNode * t = findFirstChildOfType(e, DOMNode::TEXT_NODE);
			if (t != NULL) {
				sb.sbXMLChCat(t->getNodeValue());
			}

		}

		retDoc->release();

		char * msg = XMLString::transcode(sb.rawXMLChBuffer());
		ArrayJanitor<char> j_msg(msg);

		throw XSECException(XSECException::HTTPURIInputStreamError,
							msg);
	}

	retDoc->appendChild(retDoc->importNode(e, true));

	return retDoc;

}
<|endoftext|>


<commit_before>//
// Created by Ivan Shynkarenka on 31.07.2015.
//

#include "benchmark/cppbenchmark.h"

#include <chrono>
#include <ctime>
#include <limits>

#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#undef max
#undef min
#elif defined(unix) || defined(__unix) || defined(__unix__)
#include <sys/time.h>
#include <time.h>
#endif

const int iterations = 10000000;

BENCHMARK("std::chrono::high_resolution_clock::now", iterations)
{
    static auto timestamp = std::chrono::high_resolution_clock::now();
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    auto current = std::chrono::high_resolution_clock::now();
    uint64_t duration = std::chrono::duration_cast<std::chrono::nanoseconds>(current - timestamp).count();
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}

BENCHMARK("clock", iterations)
{
    static auto timestamp = clock();
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    auto current = clock();
    uint64_t duration = (current - timestamp) * 1000 * 1000 * 1000 / CLOCKS_PER_SEC;
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}

#if defined(_WIN32) || defined(_WIN64)
BENCHMARK("GetSystemTimePreciseAsFileTime", iterations)
{
    static uint64_t timestamp = 0;
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    FILETIME filetime;
    GetSystemTimePreciseAsFileTime(&filetime);

    ULARGE_INTEGER ularge;
    ularge.LowPart = filetime.dwLowDateTime;
    ularge.HighPart = filetime.dwHighDateTime;
    uint64_t current = ularge.QuadPart * 100;

    if (timestamp == 0)
        timestamp = current;

    uint64_t duration = (current - timestamp);
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}
#endif

#if defined(_WIN32) || defined(_WIN64)
BENCHMARK("GetTickCount", iterations)
{
    static DWORD timestamp = GetTickCount();
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    DWORD current = GetTickCount();
    uint64_t duration = (current - timestamp) * 1000 * 1000;
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}
#endif

#if defined(_WIN32) || defined(_WIN64)
BENCHMARK("GetTickCount64", iterations)
{
    static ULONGLONG timestamp = GetTickCount64();
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    ULONGLONG current = GetTickCount64();
    uint64_t duration = (current - timestamp) * 1000 * 1000;
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}
#endif

#if defined(_WIN32) || defined(_WIN64)
LARGE_INTEGER QueryPerformanceCounter()
{
    LARGE_INTEGER current;
    QueryPerformanceCounter(&current);
    return current;
}

LARGE_INTEGER QueryPerformanceFrequency()
{
    LARGE_INTEGER frequency;
    QueryPerformanceFrequency(&frequency);
    return frequency;
}

BENCHMARK("QueryPerformanceCounter", iterations)
{
    static LARGE_INTEGER frequency = QueryPerformanceFrequency();
    static LARGE_INTEGER timestamp = QueryPerformanceCounter();
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    LARGE_INTEGER current = QueryPerformanceCounter();
    uint64_t duration = (current.QuadPart - timestamp.QuadPart) * 1000 * 1000 * 1000 / frequency.QuadPart;
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}
#endif

#if defined(_MSC_VER)
BENCHMARK("__rdtsc", iterations)
{
    static uint64_t timestamp = __rdtsc();
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    uint64_t current = __rdtsc();
    uint64_t duration = current - timestamp;
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min-clock-cycles", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max-clock-cycles", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min-clock-cycles", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max-clock-cycles", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}
#endif

#if defined(unix) || defined(__unix) || defined(__unix__)
struct timespec clock_gettime()
{
    struct timespec current;
    clock_gettime(CLOCK_REALTIME, &current);
    return current;
}

BENCHMARK("clock_gettime", iterations)
{
    static struct timespec timestamp = clock_gettime();
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    struct timespec current = clock_gettime();
    uint64_t duration = ((current.tv_sec - timestamp.tv_sec) * 1000 * 1000 * 1000) + (current.tv_nsec - timestamp.tv_nsec);
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}
#endif

#if defined(unix) || defined(__unix) || defined(__unix__)
struct timeval gettimeofday()
{
    struct timeval current;
    gettimeofday(&current, nullptr);
    return current;
}

BENCHMARK("gettimeofday", iterations)
{
    static struct timeval timestamp = gettimeofday();
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    struct timeval current = gettimeofday();
    uint64_t duration = ((current.tv_sec - timestamp.tv_sec) * 1000 * 1000 * 1000) + (current.tv_usec - timestamp.tv_usec) * 1000;
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}
#endif

BENCHMARK_MAIN()
<commit_msg>Add tests for Linux timers: CLOCK_REALTIME CLOCK_REALTIME_COARSE CLOCK_MONOTONIC CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC_RAW<commit_after>//
// Created by Ivan Shynkarenka on 31.07.2015.
//

#include "benchmark/cppbenchmark.h"

#include <chrono>
#include <ctime>
#include <limits>

#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#undef max
#undef min
#elif defined(unix) || defined(__unix) || defined(__unix__)
#include <sys/time.h>
#include <time.h>
#endif

const int iterations = 10000000;

BENCHMARK("std::chrono::high_resolution_clock::now", iterations)
{
    static auto timestamp = std::chrono::high_resolution_clock::now();
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    auto current = std::chrono::high_resolution_clock::now();
    uint64_t duration = std::chrono::duration_cast<std::chrono::nanoseconds>(current - timestamp).count();
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}

BENCHMARK("clock", iterations)
{
    static auto timestamp = clock();
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    auto current = clock();
    uint64_t duration = (current - timestamp) * 1000 * 1000 * 1000 / CLOCKS_PER_SEC;
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}

#if defined(_WIN32) || defined(_WIN64)
BENCHMARK("GetSystemTimePreciseAsFileTime", iterations)
{
    static uint64_t timestamp = 0;
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    FILETIME filetime;
    GetSystemTimePreciseAsFileTime(&filetime);

    ULARGE_INTEGER ularge;
    ularge.LowPart = filetime.dwLowDateTime;
    ularge.HighPart = filetime.dwHighDateTime;
    uint64_t current = ularge.QuadPart * 100;

    if (timestamp == 0)
        timestamp = current;

    uint64_t duration = (current - timestamp);
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}
#endif

#if defined(_WIN32) || defined(_WIN64)
BENCHMARK("GetTickCount", iterations)
{
    static DWORD timestamp = GetTickCount();
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    DWORD current = GetTickCount();
    uint64_t duration = (current - timestamp) * 1000 * 1000;
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}
#endif

#if defined(_WIN32) || defined(_WIN64)
BENCHMARK("GetTickCount64", iterations)
{
    static ULONGLONG timestamp = GetTickCount64();
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    ULONGLONG current = GetTickCount64();
    uint64_t duration = (current - timestamp) * 1000 * 1000;
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}
#endif

#if defined(_WIN32) || defined(_WIN64)
LARGE_INTEGER QueryPerformanceCounter()
{
    LARGE_INTEGER current;
    QueryPerformanceCounter(&current);
    return current;
}

LARGE_INTEGER QueryPerformanceFrequency()
{
    LARGE_INTEGER frequency;
    QueryPerformanceFrequency(&frequency);
    return frequency;
}

BENCHMARK("QueryPerformanceCounter", iterations)
{
    static LARGE_INTEGER frequency = QueryPerformanceFrequency();
    static LARGE_INTEGER timestamp = QueryPerformanceCounter();
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    LARGE_INTEGER current = QueryPerformanceCounter();
    uint64_t duration = (current.QuadPart - timestamp.QuadPart) * 1000 * 1000 * 1000 / frequency.QuadPart;
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}
#endif

#if defined(_MSC_VER)
BENCHMARK("__rdtsc", iterations)
{
    static uint64_t timestamp = __rdtsc();
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    uint64_t current = __rdtsc();
    uint64_t duration = current - timestamp;
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min-clock-cycles", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max-clock-cycles", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min-clock-cycles", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max-clock-cycles", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}
#endif

#if defined(unix) || defined(__unix) || defined(__unix__)
struct timespec clock_gettime(clockid_t clockid)
{
    struct timespec current;
    clock_gettime(clockid, &current);
    return current;
}

void clock_gettime_iteration(CppBenchmark::Context& context, clockid_t clockid)
{
    static struct timespec timestamp = clock_gettime(clockid);
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    struct timespec current = clock_gettime(clockid);
    uint64_t duration = ((current.tv_sec - timestamp.tv_sec) * 1000 * 1000 * 1000) + (current.tv_nsec - timestamp.tv_nsec);
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}

BENCHMARK("clock_gettime(CLOCK_REALTIME)", iterations)
{
    clock_gettime_iteration(context, CLOCK_REALTIME);
}

BENCHMARK("clock_gettime(CLOCK_REALTIME_COARSE)", iterations)
{
    clock_gettime_iteration(context, CLOCK_REALTIME_COARSE);
}

BENCHMARK("clock_gettime(CLOCK_MONOTONIC)", iterations)
{
    clock_gettime_iteration(context, CLOCK_MONOTONIC);
}

BENCHMARK("clock_gettime(CLOCK_MONOTONIC_COARSE)", iterations)
{
    clock_gettime_iteration(context, CLOCK_MONOTONIC_COARSE);
}

BENCHMARK("clock_gettime(CLOCK_MONOTONIC_RAW)", iterations)
{
    clock_gettime_iteration(context, CLOCK_MONOTONIC_RAW);
}
#endif

#if defined(unix) || defined(__unix) || defined(__unix__)
struct timeval gettimeofday()
{
    struct timeval current;
    gettimeofday(&current, nullptr);
    return current;
}

BENCHMARK("gettimeofday", iterations)
{
    static struct timeval timestamp = gettimeofday();
    static double maxlatency = std::numeric_limits<double>::min();
    static double minlatency = std::numeric_limits<double>::max();
    static uint64_t maxresolution = std::numeric_limits<int64_t>::min();
    static uint64_t minresolution = std::numeric_limits<int64_t>::max();
    static uint64_t count = 0;

    struct timeval current = gettimeofday();
    uint64_t duration = ((current.tv_sec - timestamp.tv_sec) * 1000 * 1000 * 1000) + (current.tv_usec - timestamp.tv_usec) * 1000;
    double latency = (double)duration / ++count;
    if (duration > 0)
    {
        if (latency < minlatency)
        {
            minlatency = latency;
            context.metrics().SetCustom("latency-min", minlatency);
        }
        if (latency > maxlatency)
        {
            maxlatency = latency;
            context.metrics().SetCustom("latency-max", maxlatency);
        }
        if (duration < minresolution)
        {
            minresolution = duration;
            context.metrics().SetCustom("resolution-min", minresolution);
        }
        if (duration > maxresolution)
        {
            maxresolution = duration;
            context.metrics().SetCustom("resolution-max", maxresolution);
        }
        timestamp = current;
        count = 0;
    }
}
#endif

BENCHMARK_MAIN()
<|endoftext|>


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

#include <gtest/gtest.h>

#include <string>

#include "rclcpp/rate.hpp"

/*
   Basic tests for the Rate and WallRate clases.
 */
TEST(TestRate, rate_basics) {
  auto period = std::chrono::milliseconds(100);
  auto offset = std::chrono::milliseconds(50);
  auto epsilon = std::chrono::milliseconds(1);
  double overrun_ratio = 1.5;

  auto start = std::chrono::system_clock::now();
  rclcpp::rate::Rate r(period);
  ASSERT_FALSE(r.is_steady());
  ASSERT_TRUE(r.sleep());
  auto one = std::chrono::system_clock::now();
  auto delta = one - start;
  ASSERT_TRUE(period < delta);
  ASSERT_TRUE(period * overrun_ratio > delta);

  rclcpp::utilities::sleep_for(offset);
  ASSERT_TRUE(r.sleep());
  auto two = std::chrono::system_clock::now();
  delta = two - start;
  ASSERT_TRUE(2 * period < delta);
  ASSERT_TRUE(2 * period * overrun_ratio > delta);

  rclcpp::utilities::sleep_for(offset);
  auto two_offset = std::chrono::system_clock::now();
  r.reset();
  ASSERT_TRUE(r.sleep());
  auto three = std::chrono::system_clock::now();
  delta = three - two_offset;
  ASSERT_TRUE(period < delta);
  ASSERT_TRUE(period * overrun_ratio > delta);

  rclcpp::utilities::sleep_for(offset + period);
  auto four = std::chrono::system_clock::now();
  ASSERT_FALSE(r.sleep());
  auto five = std::chrono::system_clock::now();
  delta = five - four;
  ASSERT_TRUE(epsilon > delta);
}

TEST(TestRate, wall_rate_basics) {
  auto period = std::chrono::milliseconds(100);
  auto offset = std::chrono::milliseconds(50);
  auto epsilon = std::chrono::milliseconds(1);
  double overrun_ratio = 1.5;

  auto start = std::chrono::steady_clock::now();
  rclcpp::rate::WallRate r(period);
  ASSERT_TRUE(r.is_steady());
  ASSERT_TRUE(r.sleep());
  auto one = std::chrono::steady_clock::now();
  auto delta = one - start;
  ASSERT_TRUE(period < delta);
  ASSERT_TRUE(period * overrun_ratio > delta);

  rclcpp::utilities::sleep_for(offset);
  ASSERT_TRUE(r.sleep());
  auto two = std::chrono::steady_clock::now();
  delta = two - start;
  ASSERT_TRUE(2 * period < delta + epsilon);
  ASSERT_TRUE(2 * period * overrun_ratio > delta);

  rclcpp::utilities::sleep_for(offset);
  auto two_offset = std::chrono::steady_clock::now();
  r.reset();
  ASSERT_TRUE(r.sleep());
  auto three = std::chrono::steady_clock::now();
  delta = three - two_offset;
  ASSERT_TRUE(period < delta);
  ASSERT_TRUE(period * overrun_ratio > delta);

  rclcpp::utilities::sleep_for(offset + period);
  auto four = std::chrono::steady_clock::now();
  ASSERT_FALSE(r.sleep());
  auto five = std::chrono::steady_clock::now();
  delta = five - four;
  ASSERT_TRUE(epsilon > delta);
}
<commit_msg>fix a typo.<commit_after>// Copyright 2015 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <gtest/gtest.h>

#include <string>

#include "rclcpp/rate.hpp"

/*
   Basic tests for the Rate and WallRate classes.
 */
TEST(TestRate, rate_basics) {
  auto period = std::chrono::milliseconds(100);
  auto offset = std::chrono::milliseconds(50);
  auto epsilon = std::chrono::milliseconds(1);
  double overrun_ratio = 1.5;

  auto start = std::chrono::system_clock::now();
  rclcpp::rate::Rate r(period);
  ASSERT_FALSE(r.is_steady());
  ASSERT_TRUE(r.sleep());
  auto one = std::chrono::system_clock::now();
  auto delta = one - start;
  ASSERT_TRUE(period < delta);
  ASSERT_TRUE(period * overrun_ratio > delta);

  rclcpp::utilities::sleep_for(offset);
  ASSERT_TRUE(r.sleep());
  auto two = std::chrono::system_clock::now();
  delta = two - start;
  ASSERT_TRUE(2 * period < delta);
  ASSERT_TRUE(2 * period * overrun_ratio > delta);

  rclcpp::utilities::sleep_for(offset);
  auto two_offset = std::chrono::system_clock::now();
  r.reset();
  ASSERT_TRUE(r.sleep());
  auto three = std::chrono::system_clock::now();
  delta = three - two_offset;
  ASSERT_TRUE(period < delta);
  ASSERT_TRUE(period * overrun_ratio > delta);

  rclcpp::utilities::sleep_for(offset + period);
  auto four = std::chrono::system_clock::now();
  ASSERT_FALSE(r.sleep());
  auto five = std::chrono::system_clock::now();
  delta = five - four;
  ASSERT_TRUE(epsilon > delta);
}

TEST(TestRate, wall_rate_basics) {
  auto period = std::chrono::milliseconds(100);
  auto offset = std::chrono::milliseconds(50);
  auto epsilon = std::chrono::milliseconds(1);
  double overrun_ratio = 1.5;

  auto start = std::chrono::steady_clock::now();
  rclcpp::rate::WallRate r(period);
  ASSERT_TRUE(r.is_steady());
  ASSERT_TRUE(r.sleep());
  auto one = std::chrono::steady_clock::now();
  auto delta = one - start;
  ASSERT_TRUE(period < delta);
  ASSERT_TRUE(period * overrun_ratio > delta);

  rclcpp::utilities::sleep_for(offset);
  ASSERT_TRUE(r.sleep());
  auto two = std::chrono::steady_clock::now();
  delta = two - start;
  ASSERT_TRUE(2 * period < delta + epsilon);
  ASSERT_TRUE(2 * period * overrun_ratio > delta);

  rclcpp::utilities::sleep_for(offset);
  auto two_offset = std::chrono::steady_clock::now();
  r.reset();
  ASSERT_TRUE(r.sleep());
  auto three = std::chrono::steady_clock::now();
  delta = three - two_offset;
  ASSERT_TRUE(period < delta);
  ASSERT_TRUE(period * overrun_ratio > delta);

  rclcpp::utilities::sleep_for(offset + period);
  auto four = std::chrono::steady_clock::now();
  ASSERT_FALSE(r.sleep());
  auto five = std::chrono::steady_clock::now();
  delta = five - four;
  ASSERT_TRUE(epsilon > delta);
}
<|endoftext|>


<commit_before>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2014 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

// clang-format off

#include "xenia/gpu/texture_info.h"

namespace xe {
namespace gpu {

using namespace xe::gpu::xenos;

#define FORMAT_INFO(texture_format, format, block_width, block_height, bits_per_pixel) \
    {TextureFormat::texture_format, FormatType::format, block_width, block_height, bits_per_pixel}
const FormatInfo* FormatInfo::Get(uint32_t gpu_format) {
  static const FormatInfo format_infos[] = {
      FORMAT_INFO(k_1_REVERSE                , kUncompressed, 1, 1, 1),
      FORMAT_INFO(k_1                        , kUncompressed, 1, 1, 1),
      FORMAT_INFO(k_8                        , kUncompressed, 1, 1, 8),
      FORMAT_INFO(k_1_5_5_5                  , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_5_6_5                    , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_6_5_5                    , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_8_8_8_8                  , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_2_10_10_10               , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_8_A                      , kUncompressed, 1, 1, 8),
      FORMAT_INFO(k_8_B                      , kUncompressed, 1, 1, 8),
      FORMAT_INFO(k_8_8                      , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_Cr_Y1_Cb_Y0              , kCompressed  , 2, 1, 16),
      FORMAT_INFO(k_Y1_Cr_Y0_Cb              , kCompressed  , 2, 1, 16),
      FORMAT_INFO(kUnknown                   , kUncompressed, 0, 0, 0), // k_Shadow
      FORMAT_INFO(k_8_8_8_8_A                , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_4_4_4_4                  , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_10_11_11                 , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_11_11_10                 , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_DXT1                     , kCompressed  , 4, 4, 4),
      FORMAT_INFO(k_DXT2_3                   , kCompressed  , 4, 4, 8),
      FORMAT_INFO(k_DXT4_5                   , kCompressed  , 4, 4, 8),
      FORMAT_INFO(kUnknown                   , kUncompressed, 0, 0, 0), // k_DXV
      FORMAT_INFO(k_24_8                     , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_24_8_FLOAT               , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_16                       , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_16_16                    , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_16_16_16_16              , kUncompressed, 1, 1, 64),
      FORMAT_INFO(k_16_EXPAND                , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_16_16_EXPAND             , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_16_16_16_16_EXPAND       , kUncompressed, 1, 1, 64),
      FORMAT_INFO(k_16_FLOAT                 , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_16_16_FLOAT              , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_16_16_16_16_FLOAT        , kUncompressed, 1, 1, 64),
      FORMAT_INFO(k_32                       , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_32_32                    , kUncompressed, 1, 1, 64),
      FORMAT_INFO(k_32_32_32_32              , kUncompressed, 1, 1, 128),
      FORMAT_INFO(k_32_FLOAT                 , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_32_32_FLOAT              , kUncompressed, 1, 1, 64),
      FORMAT_INFO(k_32_32_32_32_FLOAT        , kUncompressed, 1, 1, 128),
      FORMAT_INFO(k_32_AS_8                  , kCompressed  , 4, 1, 8),
      FORMAT_INFO(k_32_AS_8_8                , kCompressed  , 2, 1, 16),
      FORMAT_INFO(k_16_MPEG                  , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_16_16_MPEG               , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_8_INTERLACED             , kUncompressed, 1, 1, 8),
      FORMAT_INFO(k_32_AS_8_INTERLACED       , kCompressed  , 4, 1, 8),
      FORMAT_INFO(k_32_AS_8_8_INTERLACED     , kCompressed  , 1, 1, 16),
      FORMAT_INFO(k_16_INTERLACED            , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_16_MPEG_INTERLACED       , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_16_16_MPEG_INTERLACED    , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_DXN                      , kCompressed  , 4, 4, 8),
      FORMAT_INFO(k_8_8_8_8_AS_16_16_16_16   , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_DXT1_AS_16_16_16_16      , kCompressed  , 4, 4, 4),
      FORMAT_INFO(k_DXT2_3_AS_16_16_16_16    , kCompressed  , 4, 4, 8),
      FORMAT_INFO(k_DXT4_5_AS_16_16_16_16    , kCompressed  , 4, 4, 8),
      FORMAT_INFO(k_2_10_10_10_AS_16_16_16_16, kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_10_11_11_AS_16_16_16_16  , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_11_11_10_AS_16_16_16_16  , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_32_32_32_FLOAT           , kUncompressed, 1, 1, 96),
      FORMAT_INFO(k_DXT3A                    , kCompressed  , 4, 4, 4),
      FORMAT_INFO(k_DXT5A                    , kCompressed  , 4, 4, 4),
      FORMAT_INFO(k_CTX1                     , kCompressed  , 4, 4, 4),
      FORMAT_INFO(k_DXT3A_AS_1_1_1_1         , kCompressed  , 4, 4, 4),
      FORMAT_INFO(kUnknown                   , kUncompressed, 0, 0, 0), // k_2_10_10_10_FLOAT
  };
  return &format_infos[gpu_format];
}
#undef FORMAT_INFO

}  //  namespace gpu
}  //  namespace xe
<commit_msg>GPU: Make the format info table 64 statically elements again.<commit_after>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2014 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

// clang-format off

#include "xenia/gpu/texture_info.h"

namespace xe {
namespace gpu {

using namespace xe::gpu::xenos;

#define FORMAT_INFO(texture_format, format, block_width, block_height, bits_per_pixel) \
    {TextureFormat::texture_format, FormatType::format, block_width, block_height, bits_per_pixel}
const FormatInfo* FormatInfo::Get(uint32_t gpu_format) {
  static const FormatInfo format_infos[64] = {
      FORMAT_INFO(k_1_REVERSE                , kUncompressed, 1, 1, 1),
      FORMAT_INFO(k_1                        , kUncompressed, 1, 1, 1),
      FORMAT_INFO(k_8                        , kUncompressed, 1, 1, 8),
      FORMAT_INFO(k_1_5_5_5                  , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_5_6_5                    , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_6_5_5                    , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_8_8_8_8                  , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_2_10_10_10               , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_8_A                      , kUncompressed, 1, 1, 8),
      FORMAT_INFO(k_8_B                      , kUncompressed, 1, 1, 8),
      FORMAT_INFO(k_8_8                      , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_Cr_Y1_Cb_Y0              , kCompressed  , 2, 1, 16),
      FORMAT_INFO(k_Y1_Cr_Y0_Cb              , kCompressed  , 2, 1, 16),
      FORMAT_INFO(kUnknown                   , kUncompressed, 0, 0, 0), // k_Shadow
      FORMAT_INFO(k_8_8_8_8_A                , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_4_4_4_4                  , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_10_11_11                 , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_11_11_10                 , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_DXT1                     , kCompressed  , 4, 4, 4),
      FORMAT_INFO(k_DXT2_3                   , kCompressed  , 4, 4, 8),
      FORMAT_INFO(k_DXT4_5                   , kCompressed  , 4, 4, 8),
      FORMAT_INFO(kUnknown                   , kUncompressed, 0, 0, 0), // k_DXV
      FORMAT_INFO(k_24_8                     , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_24_8_FLOAT               , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_16                       , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_16_16                    , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_16_16_16_16              , kUncompressed, 1, 1, 64),
      FORMAT_INFO(k_16_EXPAND                , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_16_16_EXPAND             , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_16_16_16_16_EXPAND       , kUncompressed, 1, 1, 64),
      FORMAT_INFO(k_16_FLOAT                 , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_16_16_FLOAT              , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_16_16_16_16_FLOAT        , kUncompressed, 1, 1, 64),
      FORMAT_INFO(k_32                       , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_32_32                    , kUncompressed, 1, 1, 64),
      FORMAT_INFO(k_32_32_32_32              , kUncompressed, 1, 1, 128),
      FORMAT_INFO(k_32_FLOAT                 , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_32_32_FLOAT              , kUncompressed, 1, 1, 64),
      FORMAT_INFO(k_32_32_32_32_FLOAT        , kUncompressed, 1, 1, 128),
      FORMAT_INFO(k_32_AS_8                  , kCompressed  , 4, 1, 8),
      FORMAT_INFO(k_32_AS_8_8                , kCompressed  , 2, 1, 16),
      FORMAT_INFO(k_16_MPEG                  , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_16_16_MPEG               , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_8_INTERLACED             , kUncompressed, 1, 1, 8),
      FORMAT_INFO(k_32_AS_8_INTERLACED       , kCompressed  , 4, 1, 8),
      FORMAT_INFO(k_32_AS_8_8_INTERLACED     , kCompressed  , 1, 1, 16),
      FORMAT_INFO(k_16_INTERLACED            , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_16_MPEG_INTERLACED       , kUncompressed, 1, 1, 16),
      FORMAT_INFO(k_16_16_MPEG_INTERLACED    , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_DXN                      , kCompressed  , 4, 4, 8),
      FORMAT_INFO(k_8_8_8_8_AS_16_16_16_16   , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_DXT1_AS_16_16_16_16      , kCompressed  , 4, 4, 4),
      FORMAT_INFO(k_DXT2_3_AS_16_16_16_16    , kCompressed  , 4, 4, 8),
      FORMAT_INFO(k_DXT4_5_AS_16_16_16_16    , kCompressed  , 4, 4, 8),
      FORMAT_INFO(k_2_10_10_10_AS_16_16_16_16, kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_10_11_11_AS_16_16_16_16  , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_11_11_10_AS_16_16_16_16  , kUncompressed, 1, 1, 32),
      FORMAT_INFO(k_32_32_32_FLOAT           , kUncompressed, 1, 1, 96),
      FORMAT_INFO(k_DXT3A                    , kCompressed  , 4, 4, 4),
      FORMAT_INFO(k_DXT5A                    , kCompressed  , 4, 4, 4),
      FORMAT_INFO(k_CTX1                     , kCompressed  , 4, 4, 4),
      FORMAT_INFO(k_DXT3A_AS_1_1_1_1         , kCompressed  , 4, 4, 4),
      FORMAT_INFO(kUnknown                   , kUncompressed, 0, 0, 0), // k_2_10_10_10_FLOAT
      FORMAT_INFO(kUnknown                   , kUncompressed, 0, 0, 0), // invalid
  };
  return &format_infos[gpu_format];
}
#undef FORMAT_INFO

}  //  namespace gpu
}  //  namespace xe
<|endoftext|>


<commit_before>#ifndef STAN_MATH_GPU_ERR_CHECK_SYMMETRIC_HPP
#define STAN_MATH_GPU_ERR_CHECK_SYMMETRIC_HPP
#ifdef STAN_OPENCL
#include <stan/math/gpu/matrix_gpu.hpp>
#include <stan/math/prim/scal/err/domain_error.hpp>
#include <stan/math/gpu/kernels/check_symmetric.hpp>

namespace stan {
namespace math {
/**
 * Check if the matrix_gpu is symmetric
 *
 * @param function Function name (for error messages)
 * @param name Variable name (for error messages)
 * @param y matrix_gpu to test
 *
 * @throw std::domain_error if
 *    the matrix is not symmetric.
 */
inline void check_symmetric(const char* function, const char* name,
                            const matrix_gpu& y) {
  if (y.size() == 0)
    return;
  check_square(function, name, y);
  cl::CommandQueue cmd_queue = opencl_context.queue();
  cl::Context& ctx = opencl_context.context();
  try {
    int symmetric_flag = 1;
    cl::Buffer buffer_symmetric_flag(ctx, CL_MEM_READ_WRITE, sizeof(int));
    cmd_queue.enqueueWriteBuffer(buffer_symmetric_flag, CL_TRUE, 0, sizeof(int),
                                 &symmetric_flag);
    opencl_kernels::check_symmetric(cl::NDRange(y.rows(), y.cols()), y.buffer(),
                                    buffer_symmetric_flag, y.rows(), y.cols(),
                                    math::CONSTRAINT_TOLERANCE);
    cmd_queue.enqueueReadBuffer(buffer_symmetric_flag, CL_TRUE, 0, sizeof(int),
                                &symmetric_flag);
    //  if the matrix is not symmetric
    if (!symmetric_flag) {
      domain_error(function, name, "is not symmetric", "");
    }
  } catch (const cl::Error& e) {
    check_opencl_error("symmetric_check", e);
  }
}

}  // namespace math
}  // namespace stan
#endif
#endif
<commit_msg>We did not have the files for check_square and constraint_tolerance inside of check_symmetric<commit_after>#ifndef STAN_MATH_GPU_ERR_CHECK_SYMMETRIC_HPP
#define STAN_MATH_GPU_ERR_CHECK_SYMMETRIC_HPP
#ifdef STAN_OPENCL
#include <stan/math/gpu/matrix_gpu.hpp>
#include <stan/math/gpu/err/check_square.hpp>
#include <stan/math/prim/scal/err/domain_error.hpp>
#include <stan/math/prim/mat/err/constraint_tolerance.hpp>
#include <stan/math/gpu/kernels/check_symmetric.hpp>

namespace stan {
namespace math {
/**
 * Check if the matrix_gpu is symmetric
 *
 * @param function Function name (for error messages)
 * @param name Variable name (for error messages)
 * @param y matrix_gpu to test
 *
 * @throw std::domain_error if
 *    the matrix is not symmetric.
 */
inline void check_symmetric(const char* function, const char* name,
                            const matrix_gpu& y) {
  if (y.size() == 0)
    return;
  check_square(function, name, y);
  cl::CommandQueue cmd_queue = opencl_context.queue();
  cl::Context& ctx = opencl_context.context();
  try {
    int symmetric_flag = 1;
    cl::Buffer buffer_symmetric_flag(ctx, CL_MEM_READ_WRITE, sizeof(int));
    cmd_queue.enqueueWriteBuffer(buffer_symmetric_flag, CL_TRUE, 0, sizeof(int),
                                 &symmetric_flag);
    opencl_kernels::check_symmetric(cl::NDRange(y.rows(), y.cols()), y.buffer(),
                                    buffer_symmetric_flag, y.rows(), y.cols(),
                                    math::CONSTRAINT_TOLERANCE);
    cmd_queue.enqueueReadBuffer(buffer_symmetric_flag, CL_TRUE, 0, sizeof(int),
                                &symmetric_flag);
    //  if the matrix is not symmetric
    if (!symmetric_flag) {
      domain_error(function, name, "is not symmetric", "");
    }
  } catch (const cl::Error& e) {
    check_opencl_error("symmetric_check", e);
  }
}

}  // namespace math
}  // namespace stan
#endif
#endif
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_MAT_FUN_COV_SQ_EXP_HPP
#define STAN_MATH_PRIM_MAT_FUN_COV_SQ_EXP_HPP

#include <stan/math/prim/scal/meta/return_type.hpp>
#include <stan/math/prim/scal/err/check_size_match.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/prim/mat/fun/squared_distance.hpp>
#include <stan/math/prim/scal/err/check_not_nan.hpp>
#include <stan/math/prim/scal/err/check_positive.hpp>
#include <stan/math/prim/scal/fun/square.hpp>

namespace stan {
  namespace math {

    /**
     * Returns a squared exponential kernel.
     *
     * @param x std::vector of a type that can be square distance
     * @param sigma standard deviation
     * @param l length scale
     * @return squared distance
     * @throw std::domain_error if sigma <= 0, l <= 0, or
     *   x is nan or infinite
     */
    template<typename T_x, typename T_sigma, typename T_l>
    inline typename
    Eigen::Matrix<typename stan::return_type<T_x, T_sigma, T_l>::type,
                  Eigen::Dynamic, Eigen::Dynamic>
    cov_sq_exp(const std::vector<T_x>& x,
               T_sigma& sigma,
               T_l& l) {
      using std::exp;
      stan::math::check_positive("cov_sq_exp", "sigma", sigma);
      stan::math::check_positive("cov_sq_exp", "l", l);
      for (size_t n = 0; n < x.size(); n++)
        stan::math::check_not_nan("cov_sq_exp", "x", x[n]);

      Eigen::Matrix<typename stan::return_type<T_x, T_sigma, T_l>::type,
                    Eigen::Dynamic, Eigen::Dynamic>
        cov(x.size(), x.size());

      if (x.size() == 0)
        return cov;

      T_sigma sigma_sq = square(sigma);
      T_l neg_half_inv_l_sq = - 0.5 / square(l);

      for (size_t i = 0; i < x.size(); i++) {
        cov(i, i) = sigma_sq;
        for (size_t j = i + 1; j < x.size(); j++) {
          stan::math::check_size_match("cov_sq_exp",
                                       "x", stan::length(x[i]),
                                       "x", stan::length(x[j]));
          cov(i, j) = sigma_sq * exp(squared_distance(x[i], x[j]) * neg_half_inv_l_sq);
          cov(j, i) = cov(i, j);
        }
      }
      return cov;
    }

    /**
     * Returns a squared exponential kernel.
     *
     * @param x std::vector of a type that can be square distance
     * @param sigma standard deviation
     * @param l length scale
     * @return squared distance
     * @throw std::domain_error if sigma <= 0, l <= 0, or
     *   x is nan or infinite
     */
    template<typename T_x1, typename T_x2, typename T_sigma, typename T_l>
    inline typename
    Eigen::Matrix<typename stan::return_type<T_x1, T_x2, T_sigma, T_l>::type,
                  Eigen::Dynamic, Eigen::Dynamic>
    cov_sq_exp(const std::vector<T_x1>& x1,
               const std::vector<T_x2>& x2,
               T_sigma& sigma,
               T_l& l) {
      using std::exp;
      stan::math::check_positive("cov_sq_exp", "sigma", sigma);
      stan::math::check_positive("cov_sq_exp", "l", l);
      for (size_t n = 0; n < x1.size(); n++)
        stan::math::check_not_nan("cov_sq_exp", "x1", x1[n]);
      for (size_t n = 0; n < x2.size(); n++)
        stan::math::check_not_nan("cov_sq_exp", "x2", x2[n]);

      Eigen::Matrix<typename stan::return_type<T_x1, T_x2, T_sigma, T_l>::type,
                    Eigen::Dynamic, Eigen::Dynamic>
        cov(x1.size(), x2.size());
      if (x1.size() == 0 || x2.size() == 0)
        return cov;

      T_sigma sigma_sq = square(sigma);
      T_l neg_half_inv_l_sq = - 0.5 / square(l);

      for (size_t i = 0; i < x1.size(); i++) {
        for (size_t j = 0; j < x2.size(); j++) {
          stan::math::check_size_match("cov_sq_exp",
                                       "x1", stan::length(x1[i]),
                                       "x2", stan::length(x2[j]));
          cov(i, j) = sigma_sq * exp(squared_distance(x1[i], x2[j]) * neg_half_inv_l_sq);
        }
      }
      return cov;
    }
  }

}
#endif
<commit_msg>fixed comment to match args; but what exactly does it mean for a vector to be a square distance?<commit_after>#ifndef STAN_MATH_PRIM_MAT_FUN_COV_SQ_EXP_HPP
#define STAN_MATH_PRIM_MAT_FUN_COV_SQ_EXP_HPP

#include <stan/math/prim/scal/meta/return_type.hpp>
#include <stan/math/prim/scal/err/check_size_match.hpp>
#include <stan/math/prim/mat/fun/Eigen.hpp>
#include <stan/math/prim/mat/fun/squared_distance.hpp>
#include <stan/math/prim/scal/err/check_not_nan.hpp>
#include <stan/math/prim/scal/err/check_positive.hpp>
#include <stan/math/prim/scal/fun/square.hpp>

namespace stan {
  namespace math {

    /**
     * Returns a squared exponential kernel.
     *
     * @param x std::vector of a type that can be square distance
     * @param sigma standard deviation
     * @param l length scale
     * @return squared distance
     * @throw std::domain_error if sigma <= 0, l <= 0, or
     *   x is nan or infinite
     */
    template<typename T_x, typename T_sigma, typename T_l>
    inline typename
    Eigen::Matrix<typename stan::return_type<T_x, T_sigma, T_l>::type,
                  Eigen::Dynamic, Eigen::Dynamic>
    cov_sq_exp(const std::vector<T_x>& x,
               T_sigma& sigma,
               T_l& l) {
      using std::exp;
      stan::math::check_positive("cov_sq_exp", "sigma", sigma);
      stan::math::check_positive("cov_sq_exp", "l", l);
      for (size_t n = 0; n < x.size(); n++)
        stan::math::check_not_nan("cov_sq_exp", "x", x[n]);

      Eigen::Matrix<typename stan::return_type<T_x, T_sigma, T_l>::type,
                    Eigen::Dynamic, Eigen::Dynamic>
        cov(x.size(), x.size());

      if (x.size() == 0)
        return cov;

      T_sigma sigma_sq = square(sigma);
      T_l neg_half_inv_l_sq = - 0.5 / square(l);

      for (size_t i = 0; i < x.size(); i++) {
        cov(i, i) = sigma_sq;
        for (size_t j = i + 1; j < x.size(); j++) {
          stan::math::check_size_match("cov_sq_exp",
                                       "x", stan::length(x[i]),
                                       "x", stan::length(x[j]));
          cov(i, j) = sigma_sq * exp(squared_distance(x[i], x[j]) * neg_half_inv_l_sq);
          cov(j, i) = cov(i, j);
        }
      }
      return cov;
    }

    /**
     * Returns a squared exponential kernel.
     *
     * @param x1 std::vector of a type that can be square distance
     * @param x2 std::vector of a type that can be square distance
     * @param sigma standard deviation
     * @param l length scale
     * @return squared distance
     * @throw std::domain_error if sigma <= 0, l <= 0, or
     *   x is nan or infinite
     */
    template<typename T_x1, typename T_x2, typename T_sigma, typename T_l>
    inline typename
    Eigen::Matrix<typename stan::return_type<T_x1, T_x2, T_sigma, T_l>::type,
                  Eigen::Dynamic, Eigen::Dynamic>
    cov_sq_exp(const std::vector<T_x1>& x1,
               const std::vector<T_x2>& x2,
               T_sigma& sigma,
               T_l& l) {
      using std::exp;
      stan::math::check_positive("cov_sq_exp", "sigma", sigma);
      stan::math::check_positive("cov_sq_exp", "l", l);
      for (size_t n = 0; n < x1.size(); n++)
        stan::math::check_not_nan("cov_sq_exp", "x1", x1[n]);
      for (size_t n = 0; n < x2.size(); n++)
        stan::math::check_not_nan("cov_sq_exp", "x2", x2[n]);

      Eigen::Matrix<typename stan::return_type<T_x1, T_x2, T_sigma, T_l>::type,
                    Eigen::Dynamic, Eigen::Dynamic>
        cov(x1.size(), x2.size());
      if (x1.size() == 0 || x2.size() == 0)
        return cov;

      T_sigma sigma_sq = square(sigma);
      T_l neg_half_inv_l_sq = - 0.5 / square(l);

      for (size_t i = 0; i < x1.size(); i++) {
        for (size_t j = 0; j < x2.size(); j++) {
          stan::math::check_size_match("cov_sq_exp",
                                       "x1", stan::length(x1[i]),
                                       "x2", stan::length(x2[j]));
          cov(i, j) = sigma_sq * exp(squared_distance(x1[i], x2[j]) * neg_half_inv_l_sq);
        }
      }
      return cov;
    }
  }

}
#endif
<|endoftext|>


<commit_before>#ifndef STAN_MATH_REV_FUNCTOR_ODE_ADJOINT_HPP
#define STAN_MATH_REV_FUNCTOR_ODE_ADJOINT_HPP

#include <stan/math/rev/meta.hpp>
#include <stan/math/prim/fun/eval.hpp>
#include <stan/math/rev/functor/cvodes_integrator_adjoint.hpp>
#include <ostream>
#include <vector>

namespace stan {
namespace math {

/**
 * Solve the ODE initial value problem y' = f(t, y), y(t0) = y0 at a set of
 * times, { t1, t2, t3, ... } using the stiff backward differentiation formula
 * BDF solver from CVODES.
 *
 * \p f must define an operator() with the signature as:
 *   template<typename T_t, typename T_y, typename... T_Args>
 *   Eigen::Matrix<stan::return_type_t<T_t, T_y, T_Args...>, Eigen::Dynamic, 1>
 *     operator()(const T_t& t, const Eigen::Matrix<T_y, Eigen::Dynamic, 1>& y,
 *     std::ostream* msgs, const T_Args&... args);
 *
 * t is the time, y is the state, msgs is a stream for error messages, and args
 * are optional arguments passed to the ODE solve function (which are passed
 * through to \p f without modification).
 *
 * @tparam F Type of ODE right hand side
 * @tparam T_0 Type of initial time
 * @tparam T_ts Type of output times
 * @tparam T_Args Types of pass-through parameters
 *
 * @param function_name Calling function name (for printing debugging messages)
 * @param f Right hand side of the ODE
 * @param y0 Initial state
 * @param t0 Initial time
 * @param ts Times at which to solve the ODE at. All values must be sorted and
 *   not less than t0.
 * @param relative_tolerance_forward Relative tolerance for forward problem
 * passed to CVODES
 * @param absolute_tolerance_forward Absolute tolerance for forward problem
 * passed to CVODES
 * @param relative_tolerance_backward Relative tolerance for backward problem
 * passed to CVODES
 * @param absolute_tolerance_backward Absolute tolerance for backward problem
 * passed to CVODES
 * @param relative_tolerance_quadrature Relative tolerance for quadrature
 * problem passed to CVODES
 * @param absolute_tolerance_quadrature Absolute tolerance for quadrature
 * problem passed to CVODES
 * @param max_num_steps Upper limit on the number of integration steps to
 *   take between each output (error if exceeded)
 * @param num_steps_between_checkpoints Number of integrator steps after which a
 * checkpoint is stored for the backward pass
 * @param interpolation_polynomial type of polynomial used for interpolation
 * @param solver_forward solver used for forward pass
 * @param solver_backward solver used for backward pass
 * @param[in, out] msgs the print stream for warning messages
 * @param args Extra arguments passed unmodified through to ODE right hand side
 * @return Solution to ODE at times \p ts
 */
template <typename F, typename T_y0, typename T_t0, typename T_ts,
          typename... T_Args, require_eigen_col_vector_t<T_y0>* = nullptr>
std::vector<Eigen::Matrix<stan::return_type_t<T_y0, T_t0, T_ts, T_Args...>,
                          Eigen::Dynamic, 1>>
ode_adjoint_impl(const char* function_name, const F& f, const T_y0& y0,
                 const T_t0& t0, const std::vector<T_ts>& ts,
                 double relative_tolerance_forward,
                 Eigen::VectorXd absolute_tolerance_forward,
                 double relative_tolerance_backward,
                 Eigen::VectorXd absolute_tolerance_backward,
                 double relative_tolerance_quadrature,
                 double absolute_tolerance_quadrature,
                 long int max_num_steps,                  // NOLINT(runtime/int)
                 long int num_steps_between_checkpoints,  // NOLINT(runtime/int)
                 int interpolation_polynomial, int solver_forward,
                 int solver_backward, std::ostream* msgs,
                 const T_Args&... args) {
  /*
  const auto& args_ref_tuple = std::make_tuple(to_ref(args)...);
  return apply(
      [&](const auto&... args_refs) {
        auto integrator
            = new stan::math::cvodes_integrator_adjoint_vari<CV_BDF, F, T_y0,
  T_t0, T_ts, T_Args...>( function_name, f, y0, t0, ts, relative_tolerance,
                          absolute_tolerance, absolute_tolerance_B,
  absolute_tolerance_QB, steps_checkpoint, max_num_steps, msgs, args_refs...);
        return (*integrator)();
      }, args_ref_tuple);
      */
  /*
  const auto& args_eval_tuple = std::make_tuple(eval(args)...);
  return apply(
      [&](const auto&... args_eval) {
        auto integrator
            = new stan::math::cvodes_integrator_adjoint_vari<CV_BDF, F, T_y0,
  T_t0, T_ts, T_Args...>( function_name, f, y0, t0, ts, relative_tolerance,
                          absolute_tolerance, absolute_tolerance_B,
  absolute_tolerance_QB, steps_checkpoint, max_num_steps, msgs, args_eval...);
        return (*integrator)();
      }, args_eval_tuple);
      */
  /*
  auto integrator
      = new stan::math::cvodes_integrator_adjoint_vari<CV_BDF, F, T_y0, T_t0,
                                                       T_ts, T_Args...>(
          function_name, f, y0, t0, ts, relative_tolerance, absolute_tolerance,
          absolute_tolerance_B, absolute_tolerance_QB, steps_checkpoint,
          max_num_steps, msgs, eval(args)...);
  return (*integrator)();
  */
  auto integrator = new stan::math::cvodes_integrator_adjoint_vari<
      F, plain_type_t<T_y0>, T_t0, T_ts, ref_type_t<T_Args>...>(
      function_name, f, eval(y0), t0, ts, relative_tolerance_forward,
      absolute_tolerance_forward, relative_tolerance_backward,
      absolute_tolerance_backward, relative_tolerance_quadrature,
      absolute_tolerance_quadrature, max_num_steps,
      num_steps_between_checkpoints, interpolation_polynomial, solver_forward,
      solver_backward, msgs, to_ref(args)...);
  return (*integrator)();
}

/**
 * Solve the ODE initial value problem y' = f(t, y), y(t0) = y0 at a set of
 * times, { t1, t2, t3, ... } using the stiff backward differentiation formula
 * BDF solver from CVODES.
 *
 * \p f must define an operator() with the signature as:
 *   template<typename T_t, typename T_y, typename... T_Args>
 *   Eigen::Matrix<stan::return_type_t<T_t, T_y, T_Args...>, Eigen::Dynamic, 1>
 *     operator()(const T_t& t, const Eigen::Matrix<T_y, Eigen::Dynamic, 1>& y,
 *     std::ostream* msgs, const T_Args&... args);
 *
 * t is the time, y is the state, msgs is a stream for error messages, and args
 * are optional arguments passed to the ODE solve function (which are passed
 * through to \p f without modification).
 *
 * @tparam F Type of ODE right hand side
 * @tparam T_0 Type of initial time
 * @tparam T_ts Type of output times
 * @tparam T_Args Types of pass-through parameters
 *
 * @param f Right hand side of the ODE
 * @param y0 Initial state
 * @param t0 Initial time
 * @param ts Times at which to solve the ODE at. All values must be sorted and
 *   not less than t0.
 * @param relative_tolerance Relative tolerance passed to CVODES
 * @param absolute_tolerance Absolute tolerance passed to CVODES
 * @param max_num_steps Upper limit on the number of integration steps to
 *   take between each output (error if exceeded)
 * @param[in, out] msgs the print stream for warning messages
 * @param args Extra arguments passed unmodified through to ODE right hand side
 * @return Solution to ODE at times \p ts
 */
template <typename F, typename T_y0, typename T_t0, typename T_ts,
          typename... T_Args, require_eigen_col_vector_t<T_y0>* = nullptr>
std::vector<Eigen::Matrix<stan::return_type_t<T_y0, T_t0, T_ts, T_Args...>,
                          Eigen::Dynamic, 1>>
ode_adjoint_tol_ctl(
    const F& f, const T_y0& y0, const T_t0& t0, const std::vector<T_ts>& ts,
    double relative_tolerance_forward,
    Eigen::VectorXd absolute_tolerance_forward,
    double relative_tolerance_backward,
    Eigen::VectorXd absolute_tolerance_backward,
    double relative_tolerance_quadrature, double absolute_tolerance_quadrature,
    long int max_num_steps,                  // NOLINT(runtime/int)
    long int num_steps_between_checkpoints,  // NOLINT(runtime/int)
    int interpolation_polynomial, int solver_forward, int solver_backward,
    std::ostream* msgs, const T_Args&... args) {
  return ode_adjoint_impl(
      "ode_adjoint_tol_ctl", f, y0, t0, ts, relative_tolerance_forward,
      absolute_tolerance_forward, relative_tolerance_backward,
      absolute_tolerance_backward, relative_tolerance_quadrature,
      absolute_tolerance_quadrature, max_num_steps,
      num_steps_between_checkpoints, interpolation_polynomial, solver_forward,
      solver_backward, msgs, args...);
}

template <typename F, typename T_y0, typename T_t0, typename T_ts,
          typename... T_Args, require_eigen_col_vector_t<T_y0>* = nullptr>
std::vector<Eigen::Matrix<stan::return_type_t<T_y0, T_t0, T_ts, T_Args...>,
                          Eigen::Dynamic, 1>>
ode_adjoint_tol(const F& f, const T_y0& y0, const T_t0& t0,
                const std::vector<T_ts>& ts, double relative_tolerance,
                double absolute_tolerance,
                long int max_num_steps,  // NOLINT(runtime/int)
                std::ostream* msgs, const T_Args&... args) {
  const int N = y0.size();
  const Eigen::VectorXd absolute_tolerance_forward
      = Eigen::VectorXd::Constant(N, absolute_tolerance / 100.0);
  const Eigen::VectorXd absolute_tolerance_backward
      = Eigen::VectorXd::Constant(N, absolute_tolerance / 10.0);
  const long int num_steps_between_checkpoints = 250;
  const int interpolation_polynomial = CV_HERMITE;
  const int solver_forward = CV_BDF;
  const int solver_backward = CV_BDF;
  return ode_adjoint_impl(
      "ode_adjoint_tol", f, y0, t0, ts, relative_tolerance,
      absolute_tolerance_forward, relative_tolerance,
      absolute_tolerance_backward, relative_tolerance, absolute_tolerance,
      max_num_steps, num_steps_between_checkpoints, interpolation_polynomial,
      solver_forward, solver_backward, msgs, args...);
}

}  // namespace math
}  // namespace stan
#endif
<commit_msg>cpplint<commit_after>#ifndef STAN_MATH_REV_FUNCTOR_ODE_ADJOINT_HPP
#define STAN_MATH_REV_FUNCTOR_ODE_ADJOINT_HPP

#include <stan/math/rev/meta.hpp>
#include <stan/math/prim/fun/eval.hpp>
#include <stan/math/rev/functor/cvodes_integrator_adjoint.hpp>
#include <ostream>
#include <vector>

namespace stan {
namespace math {

/**
 * Solve the ODE initial value problem y' = f(t, y), y(t0) = y0 at a set of
 * times, { t1, t2, t3, ... } using the stiff backward differentiation formula
 * BDF solver from CVODES.
 *
 * \p f must define an operator() with the signature as:
 *   template<typename T_t, typename T_y, typename... T_Args>
 *   Eigen::Matrix<stan::return_type_t<T_t, T_y, T_Args...>, Eigen::Dynamic, 1>
 *     operator()(const T_t& t, const Eigen::Matrix<T_y, Eigen::Dynamic, 1>& y,
 *     std::ostream* msgs, const T_Args&... args);
 *
 * t is the time, y is the state, msgs is a stream for error messages, and args
 * are optional arguments passed to the ODE solve function (which are passed
 * through to \p f without modification).
 *
 * @tparam F Type of ODE right hand side
 * @tparam T_0 Type of initial time
 * @tparam T_ts Type of output times
 * @tparam T_Args Types of pass-through parameters
 *
 * @param function_name Calling function name (for printing debugging messages)
 * @param f Right hand side of the ODE
 * @param y0 Initial state
 * @param t0 Initial time
 * @param ts Times at which to solve the ODE at. All values must be sorted and
 *   not less than t0.
 * @param relative_tolerance_forward Relative tolerance for forward problem
 * passed to CVODES
 * @param absolute_tolerance_forward Absolute tolerance for forward problem
 * passed to CVODES
 * @param relative_tolerance_backward Relative tolerance for backward problem
 * passed to CVODES
 * @param absolute_tolerance_backward Absolute tolerance for backward problem
 * passed to CVODES
 * @param relative_tolerance_quadrature Relative tolerance for quadrature
 * problem passed to CVODES
 * @param absolute_tolerance_quadrature Absolute tolerance for quadrature
 * problem passed to CVODES
 * @param max_num_steps Upper limit on the number of integration steps to
 *   take between each output (error if exceeded)
 * @param num_steps_between_checkpoints Number of integrator steps after which a
 * checkpoint is stored for the backward pass
 * @param interpolation_polynomial type of polynomial used for interpolation
 * @param solver_forward solver used for forward pass
 * @param solver_backward solver used for backward pass
 * @param[in, out] msgs the print stream for warning messages
 * @param args Extra arguments passed unmodified through to ODE right hand side
 * @return Solution to ODE at times \p ts
 */
template <typename F, typename T_y0, typename T_t0, typename T_ts,
          typename... T_Args, require_eigen_col_vector_t<T_y0>* = nullptr>
std::vector<Eigen::Matrix<stan::return_type_t<T_y0, T_t0, T_ts, T_Args...>,
                          Eigen::Dynamic, 1>>
ode_adjoint_impl(const char* function_name, const F& f, const T_y0& y0,
                 const T_t0& t0, const std::vector<T_ts>& ts,
                 double relative_tolerance_forward,
                 Eigen::VectorXd absolute_tolerance_forward,
                 double relative_tolerance_backward,
                 Eigen::VectorXd absolute_tolerance_backward,
                 double relative_tolerance_quadrature,
                 double absolute_tolerance_quadrature,
                 long int max_num_steps,                  // NOLINT(runtime/int)
                 long int num_steps_between_checkpoints,  // NOLINT(runtime/int)
                 int interpolation_polynomial, int solver_forward,
                 int solver_backward, std::ostream* msgs,
                 const T_Args&... args) {
  /*
  const auto& args_ref_tuple = std::make_tuple(to_ref(args)...);
  return apply(
      [&](const auto&... args_refs) {
        auto integrator
            = new stan::math::cvodes_integrator_adjoint_vari<CV_BDF, F, T_y0,
  T_t0, T_ts, T_Args...>( function_name, f, y0, t0, ts, relative_tolerance,
                          absolute_tolerance, absolute_tolerance_B,
  absolute_tolerance_QB, steps_checkpoint, max_num_steps, msgs, args_refs...);
        return (*integrator)();
      }, args_ref_tuple);
      */
  /*
  const auto& args_eval_tuple = std::make_tuple(eval(args)...);
  return apply(
      [&](const auto&... args_eval) {
        auto integrator
            = new stan::math::cvodes_integrator_adjoint_vari<CV_BDF, F, T_y0,
  T_t0, T_ts, T_Args...>( function_name, f, y0, t0, ts, relative_tolerance,
                          absolute_tolerance, absolute_tolerance_B,
  absolute_tolerance_QB, steps_checkpoint, max_num_steps, msgs, args_eval...);
        return (*integrator)();
      }, args_eval_tuple);
      */
  /*
  auto integrator
      = new stan::math::cvodes_integrator_adjoint_vari<CV_BDF, F, T_y0, T_t0,
                                                       T_ts, T_Args...>(
          function_name, f, y0, t0, ts, relative_tolerance, absolute_tolerance,
          absolute_tolerance_B, absolute_tolerance_QB, steps_checkpoint,
          max_num_steps, msgs, eval(args)...);
  return (*integrator)();
  */
  auto integrator = new stan::math::cvodes_integrator_adjoint_vari<
      F, plain_type_t<T_y0>, T_t0, T_ts, ref_type_t<T_Args>...>(
      function_name, f, eval(y0), t0, ts, relative_tolerance_forward,
      absolute_tolerance_forward, relative_tolerance_backward,
      absolute_tolerance_backward, relative_tolerance_quadrature,
      absolute_tolerance_quadrature, max_num_steps,
      num_steps_between_checkpoints, interpolation_polynomial, solver_forward,
      solver_backward, msgs, to_ref(args)...);
  return (*integrator)();
}

/**
 * Solve the ODE initial value problem y' = f(t, y), y(t0) = y0 at a set of
 * times, { t1, t2, t3, ... } using the stiff backward differentiation formula
 * BDF solver from CVODES.
 *
 * \p f must define an operator() with the signature as:
 *   template<typename T_t, typename T_y, typename... T_Args>
 *   Eigen::Matrix<stan::return_type_t<T_t, T_y, T_Args...>, Eigen::Dynamic, 1>
 *     operator()(const T_t& t, const Eigen::Matrix<T_y, Eigen::Dynamic, 1>& y,
 *     std::ostream* msgs, const T_Args&... args);
 *
 * t is the time, y is the state, msgs is a stream for error messages, and args
 * are optional arguments passed to the ODE solve function (which are passed
 * through to \p f without modification).
 *
 * @tparam F Type of ODE right hand side
 * @tparam T_0 Type of initial time
 * @tparam T_ts Type of output times
 * @tparam T_Args Types of pass-through parameters
 *
 * @param f Right hand side of the ODE
 * @param y0 Initial state
 * @param t0 Initial time
 * @param ts Times at which to solve the ODE at. All values must be sorted and
 *   not less than t0.
 * @param relative_tolerance Relative tolerance passed to CVODES
 * @param absolute_tolerance Absolute tolerance passed to CVODES
 * @param max_num_steps Upper limit on the number of integration steps to
 *   take between each output (error if exceeded)
 * @param[in, out] msgs the print stream for warning messages
 * @param args Extra arguments passed unmodified through to ODE right hand side
 * @return Solution to ODE at times \p ts
 */
template <typename F, typename T_y0, typename T_t0, typename T_ts,
          typename... T_Args, require_eigen_col_vector_t<T_y0>* = nullptr>
std::vector<Eigen::Matrix<stan::return_type_t<T_y0, T_t0, T_ts, T_Args...>,
                          Eigen::Dynamic, 1>>
ode_adjoint_tol_ctl(
    const F& f, const T_y0& y0, const T_t0& t0, const std::vector<T_ts>& ts,
    double relative_tolerance_forward,
    Eigen::VectorXd absolute_tolerance_forward,
    double relative_tolerance_backward,
    Eigen::VectorXd absolute_tolerance_backward,
    double relative_tolerance_quadrature, double absolute_tolerance_quadrature,
    long int max_num_steps,                  // NOLINT(runtime/int)
    long int num_steps_between_checkpoints,  // NOLINT(runtime/int)
    int interpolation_polynomial, int solver_forward, int solver_backward,
    std::ostream* msgs, const T_Args&... args) {
  return ode_adjoint_impl(
      "ode_adjoint_tol_ctl", f, y0, t0, ts, relative_tolerance_forward,
      absolute_tolerance_forward, relative_tolerance_backward,
      absolute_tolerance_backward, relative_tolerance_quadrature,
      absolute_tolerance_quadrature, max_num_steps,
      num_steps_between_checkpoints, interpolation_polynomial, solver_forward,
      solver_backward, msgs, args...);
}

template <typename F, typename T_y0, typename T_t0, typename T_ts,
          typename... T_Args, require_eigen_col_vector_t<T_y0>* = nullptr>
std::vector<Eigen::Matrix<stan::return_type_t<T_y0, T_t0, T_ts, T_Args...>,
                          Eigen::Dynamic, 1>>
ode_adjoint_tol(const F& f, const T_y0& y0, const T_t0& t0,
                const std::vector<T_ts>& ts, double relative_tolerance,
                double absolute_tolerance,
                long int max_num_steps,  // NOLINT(runtime/int)
                std::ostream* msgs, const T_Args&... args) {
  const int N = y0.size();
  const Eigen::VectorXd absolute_tolerance_forward
      = Eigen::VectorXd::Constant(N, absolute_tolerance / 100.0);
  const Eigen::VectorXd absolute_tolerance_backward
      = Eigen::VectorXd::Constant(N, absolute_tolerance / 10.0);
  const long int num_steps_between_checkpoints = 250; // NOLINT(runtime/int)
  const int interpolation_polynomial = CV_HERMITE;
  const int solver_forward = CV_BDF;
  const int solver_backward = CV_BDF;
  return ode_adjoint_impl(
      "ode_adjoint_tol", f, y0, t0, ts, relative_tolerance,
      absolute_tolerance_forward, relative_tolerance,
      absolute_tolerance_backward, relative_tolerance, absolute_tolerance,
      max_num_steps, num_steps_between_checkpoints, interpolation_polynomial,
      solver_forward, solver_backward, msgs, args...);
}

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>