<commit_before>#include "ServerClientConnection.hpp"

namespace et {
ServerClientConnection::ServerClientConnection(
    const std::shared_ptr<SocketHandler>& _socketHandler,
    const string& clientId, int _socketFd, const string& key)
    : Connection(_socketHandler, clientId, key) {
  socketFd = _socketFd;
  reader = shared_ptr<BackedReader>(
      new BackedReader(socketHandler,
                       shared_ptr<CryptoHandler>(
                           new CryptoHandler(key, CLIENT_SERVER_NONCE_MSB)),
                       _socketFd));
  writer = shared_ptr<BackedWriter>(
      new BackedWriter(socketHandler,
                       shared_ptr<CryptoHandler>(
                           new CryptoHandler(key, SERVER_CLIENT_NONCE_MSB)),
                       _socketFd));
}

ServerClientConnection::~ServerClientConnection() {
  if (socketFd != -1) {
    closeSocket();
  }
}

bool ServerClientConnection::recoverClient(int newSocketFd) {
  if (socketFd != -1) {
    closeSocket();
  }
  return recover(newSocketFd);
}
}  // namespace et
<commit_msg>more tsan<commit_after>#include "ServerClientConnection.hpp"

namespace et {
ServerClientConnection::ServerClientConnection(
    const std::shared_ptr<SocketHandler>& _socketHandler,
    const string& clientId, int _socketFd, const string& key)
    : Connection(_socketHandler, clientId, key) {
  socketFd = _socketFd;
  reader = shared_ptr<BackedReader>(
      new BackedReader(socketHandler,
                       shared_ptr<CryptoHandler>(
                           new CryptoHandler(key, CLIENT_SERVER_NONCE_MSB)),
                       _socketFd));
  writer = shared_ptr<BackedWriter>(
      new BackedWriter(socketHandler,
                       shared_ptr<CryptoHandler>(
                           new CryptoHandler(key, SERVER_CLIENT_NONCE_MSB)),
                       _socketFd));
}

ServerClientConnection::~ServerClientConnection() {
  if (socketFd != -1) {
    closeSocket();
  }
}

bool ServerClientConnection::recoverClient(int newSocketFd) {
  {
    lock_guard<std::recursive_mutex> guard(connectionMutex);
    if (socketFd != -1) {
      closeSocket();
    }
  }
  return recover(newSocketFd);
}
}  // namespace et
<|endoftext|>


<commit_before>#include <stdexcept>

#include "xz.hh"

#pragma GCC diagnostic push
#ifdef __clang__
#pragma GCC diagnostic ignored "-Wdocumentation"
#pragma GCC diagnostic ignored "-Wdocumentation-unknown-command"
#endif
#define lzma_nothrow
#include <lzma.h>
#pragma GCC diagnostic pop

// ----------------------------------------------------------------------

const unsigned char sXzSig[] = { 0xFD, '7', 'z', 'X', 'Z', 0x00 };
constexpr ssize_t sXzBufSize = 409600;

// ----------------------------------------------------------------------

bool xz_compressed(std::string input)
{
    return std::memcmp(input.c_str(), sXzSig, sizeof(sXzSig)) == 0;
}

// ----------------------------------------------------------------------

std::string xz_decompress(std::string buffer)
{
    lzma_stream strm = LZMA_STREAM_INIT; /* alloc and init lzma_stream struct */
    if (lzma_stream_decoder(&strm, UINT64_MAX, LZMA_TELL_UNSUPPORTED_CHECK | LZMA_CONCATENATED) != LZMA_OK) {
        throw std::runtime_error("lzma decompression failed 1");
    }

    strm.next_in = reinterpret_cast<const uint8_t *>(buffer.c_str());
    strm.avail_in = buffer.size();
    std::string output(sXzBufSize, ' ');
    ssize_t offset = 0;
    for (;;) {
        strm.next_out = reinterpret_cast<uint8_t *>(&*(output.begin() + offset));
        strm.avail_out = sXzBufSize;
        auto const r = lzma_code(&strm, LZMA_FINISH);
        if (r == LZMA_STREAM_END) {
            output.resize(static_cast<size_t>(offset + sXzBufSize) - strm.avail_out);
            break;
        }
        else if (r == LZMA_OK) {
            offset += sXzBufSize;
            output.resize(static_cast<size_t>(offset + sXzBufSize));
        }
        else {
            throw std::runtime_error("lzma decompression failed 2");
        }
    }
    lzma_end(&strm);
    return output;
}

// ----------------------------------------------------------------------

std::string xz_compress(std::string input)
{
    lzma_stream strm = LZMA_STREAM_INIT; /* alloc and init lzma_stream struct */
    if (lzma_easy_encoder(&strm, 9 | LZMA_PRESET_EXTREME, LZMA_CHECK_CRC64) != LZMA_OK) {
        throw std::runtime_error("lzma compression failed 1");
    }

    strm.next_in = reinterpret_cast<const uint8_t *>(input.c_str());
    strm.avail_in = input.size();
    std::string output(sXzBufSize, ' ');
    ssize_t offset = 0;
    for (;;) {
        strm.next_out = reinterpret_cast<uint8_t *>(&*(output.begin() + offset));
        strm.avail_out = sXzBufSize;
        auto const r = lzma_code(&strm, LZMA_FINISH);
        if (r == LZMA_STREAM_END) {
            output.resize(static_cast<size_t>(offset + sXzBufSize) - strm.avail_out);
            break;
        }
        else if (r == LZMA_OK) {
            offset += sXzBufSize;
            output.resize(static_cast<size_t>(offset + sXzBufSize));
        }
        else {
            throw std::runtime_error("lzma compression failed 2");
        }
    }
    lzma_end(&strm);
    return output;

} // xz_compress

// ----------------------------------------------------------------------
<commit_msg>porting to gcc 4.9<commit_after>#include <stdexcept>
#include <cstring>

#include "xz.hh"

#pragma GCC diagnostic push
#ifdef __clang__
#pragma GCC diagnostic ignored "-Wdocumentation"
#pragma GCC diagnostic ignored "-Wdocumentation-unknown-command"
#endif
#define lzma_nothrow
#include <lzma.h>
#pragma GCC diagnostic pop

// ----------------------------------------------------------------------

const unsigned char sXzSig[] = { 0xFD, '7', 'z', 'X', 'Z', 0x00 };
constexpr ssize_t sXzBufSize = 409600;

// ----------------------------------------------------------------------

bool xz_compressed(std::string input)
{
    return std::memcmp(input.c_str(), sXzSig, sizeof(sXzSig)) == 0;
}

// ----------------------------------------------------------------------

std::string xz_decompress(std::string buffer)
{
    lzma_stream strm = LZMA_STREAM_INIT; /* alloc and init lzma_stream struct */
    if (lzma_stream_decoder(&strm, UINT64_MAX, LZMA_TELL_UNSUPPORTED_CHECK | LZMA_CONCATENATED) != LZMA_OK) {
        throw std::runtime_error("lzma decompression failed 1");
    }

    strm.next_in = reinterpret_cast<const uint8_t *>(buffer.c_str());
    strm.avail_in = buffer.size();
    std::string output(sXzBufSize, ' ');
    ssize_t offset = 0;
    for (;;) {
        strm.next_out = reinterpret_cast<uint8_t *>(&*(output.begin() + offset));
        strm.avail_out = sXzBufSize;
        auto const r = lzma_code(&strm, LZMA_FINISH);
        if (r == LZMA_STREAM_END) {
            output.resize(static_cast<size_t>(offset + sXzBufSize) - strm.avail_out);
            break;
        }
        else if (r == LZMA_OK) {
            offset += sXzBufSize;
            output.resize(static_cast<size_t>(offset + sXzBufSize));
        }
        else {
            throw std::runtime_error("lzma decompression failed 2");
        }
    }
    lzma_end(&strm);
    return output;
}

// ----------------------------------------------------------------------

std::string xz_compress(std::string input)
{
    lzma_stream strm = LZMA_STREAM_INIT; /* alloc and init lzma_stream struct */
    if (lzma_easy_encoder(&strm, 9 | LZMA_PRESET_EXTREME, LZMA_CHECK_CRC64) != LZMA_OK) {
        throw std::runtime_error("lzma compression failed 1");
    }

    strm.next_in = reinterpret_cast<const uint8_t *>(input.c_str());
    strm.avail_in = input.size();
    std::string output(sXzBufSize, ' ');
    ssize_t offset = 0;
    for (;;) {
        strm.next_out = reinterpret_cast<uint8_t *>(&*(output.begin() + offset));
        strm.avail_out = sXzBufSize;
        auto const r = lzma_code(&strm, LZMA_FINISH);
        if (r == LZMA_STREAM_END) {
            output.resize(static_cast<size_t>(offset + sXzBufSize) - strm.avail_out);
            break;
        }
        else if (r == LZMA_OK) {
            offset += sXzBufSize;
            output.resize(static_cast<size_t>(offset + sXzBufSize));
        }
        else {
            throw std::runtime_error("lzma compression failed 2");
        }
    }
    lzma_end(&strm);
    return output;

} // xz_compress

// ----------------------------------------------------------------------
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 David Wicks, sansumbrella.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "Motion.hpp"
#include "Cue.h"

namespace choreograph
{

class Timeline;

///
/// Options for manipulating newly created TimelineItems.
/// Uses CRTP so we don't lose the actual type when chaining methods.
/// Do not store the TimelineOptions object, as it contains a non-owning reference.
///
template<typename Derived>
class TimelineOptionsBase
{
public:
  TimelineOptionsBase( TimelineItem &item ):
  _item( item )
  {}

  //=================================================
  // TimelineItem Interface Mirroring.
  //=================================================

  /// Set whether the item should be removed from the timeline on finish.
  Derived& removeOnFinish( bool doRemove ) { _item.setRemoveOnFinish( doRemove ); return self(); }

  /// Set the rate at which time advances for Motion.
  Derived& playbackSpeed( Time speed ) { _item.setPlaybackSpeed( speed ); return self(); }

  /// Set the initial time offset of the TimelineItem.
  /// For Cues, this sets the time in the future.
  /// For Motions, this is akin to adding a hold at the beginning of the Sequence.
  Derived& setStartTime( Time t ) { _item.setStartTime( t ); return self(); }

  /// Returns a shared_ptr to the control object for the Item. Allows you to cancel the Item later.
  TimelineItemControlRef  getControl() { return _item.getControl(); }

  /// Returns an object that cancels the Cue when it falls out of scope.
  /// You should store a ScopedCueRef in any class that captures [this] in a cued lambda.
  ScopedCancelRef         getScopedControl() { return std::make_shared<ScopedCancel>( _item.getControl() ); }

private:
  TimelineItem &_item;
  Derived& self() { return static_cast<Derived&>( *this ); }
};

///
/// TimelineOptions with no additional behaviors beyond base.
/// Returned when creating cues.
/// Do not store the TimelineOptions object, as it contains a non-owning reference.
///
class TimelineOptions : public TimelineOptionsBase<TimelineOptions>
{
public:
  TimelineOptions( TimelineItem &item )
  : TimelineOptionsBase<TimelineOptions>( item )
  {}
};

///
/// MotionOptions provide a temporary facade for manipulating a timeline Motion and its underlying Sequence.
/// All methods return a reference back to the MotionOptions object for chaining.
/// Do not store the MotionOptions object, as it contains non-owning references.
///
template<typename T>
class MotionOptions : public TimelineOptionsBase<MotionOptions<T>>
{
public:
  using SelfT = MotionOptions<T>;
  using MotionCallback = typename Motion<T>::Callback;

  MotionOptions( Motion<T> &motion, Sequence<T> &sequence, const Timeline &timeline ):
  TimelineOptionsBase<MotionOptions<T>>( motion ),
  _motion( motion ),
  _sequence( sequence ),
  _timeline( timeline )
  {}

  //=================================================
  // Motion Interface Mirroring.
  //=================================================

  /// Set function to be called when Motion starts. Receives reference to motion.
  SelfT& startFn( const MotionCallback &fn ) { _motion.setStartFn( fn ); return *this; }

  /// Set function to be called when Motion updates. Receives current target value.
  SelfT& updateFn( const typename Motion<T>::Callback &fn ) { _motion.setUpdateFn( fn ); return *this; }

  /// Set function to be called when Motion finishes. Receives reference to motion.
  SelfT& finishFn( const MotionCallback &fn ) { _motion.setFinishFn( fn ); return *this; }

  /// Set a function to be called when the current inflection point is crossed.
  /// An inflection occcurs when the Sequence moves from one Phrase to the next.
  /// You must add a phrase after this for the inflection to occur.
  SelfT& onInflection( const MotionCallback &fn ) { return onInflection( _sequence.getPhraseCount(), fn ); }
  /// Adds an inflection callback when the specified phrase index is crossed.
  SelfT& onInflection( size_t point, const MotionCallback &fn ) { _motion.addInflectionCallback( point, fn ); return *this; }

  /// Clip the motion in \t time from the current Motion playhead.
  /// Also discards any phrases we have already played up to this point.
  SelfT& cutIn( Time t ) { _motion.cutIn( t ); return *this; }

  /// Clip the motion at time \t from the beginning of the Motion's Sequence.
  /// When used after Timeline::apply, will have the same effect as cutIn().
  SelfT& cutAt( Time t ) { _motion.sliceSequence( 0, t ); return *this; }

  //=================================================
  // Sequence Interface Mirroring.
  //=================================================

  /// Set the current value of the Sequence. Acts as an instantaneous hold.
  SelfT& set( const T &value ) { _sequence.set( value ); return *this; }

  /// Construct and append a Phrase to the Sequence.
  template<template <typename> class PhraseT, typename... Args>
  SelfT& then( const T &value, Time duration, Args&&... args ) { _sequence.template then<PhraseT>( value, duration, std::forward<Args>(args)... ); return *this; }

  /// Append a phrase to the Sequence.
  SelfT& then( const PhraseRef<T> &phrase ) { _sequence.then( phrase ); return *this; }

  /// Append a sequence to the Sequence.
  SelfT& then( const Sequence<T> &sequence ) { _sequence.then( sequence ); return *this; }

  //=================================================
  // Extra Sugar.
  //=================================================

  /// Append a Hold to the end of the Sequence. Assumes you want to hold using the Sequence's current end value.
  SelfT& hold( Time duration ) { _sequence.template then<Hold>( _sequence.getEndValue(), duration ); return *this; }

  //=================================================
  // Accessors to Motion and Sequence.
  //=================================================

  Sequence<T>& getSequence() { return _sequence; }
  Motion<T>&   getMotion() { return _motion; }

private:
  Motion<T>       &_motion;
  Sequence<T>     &_sequence;
  const Timeline  &_timeline;
};

} // namespace choreograph
<commit_msg>Add holdUntil helper function.<commit_after>/*
 * Copyright (c) 2014 David Wicks, sansumbrella.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "Motion.hpp"
#include "Cue.h"

namespace choreograph
{

class Timeline;

///
/// Options for manipulating newly created TimelineItems.
/// Uses CRTP so we don't lose the actual type when chaining methods.
/// Do not store the TimelineOptions object, as it contains a non-owning reference.
///
template<typename Derived>
class TimelineOptionsBase
{
public:
  TimelineOptionsBase( TimelineItem &item ):
  _item( item )
  {}

  //=================================================
  // TimelineItem Interface Mirroring.
  //=================================================

  /// Set whether the item should be removed from the timeline on finish.
  Derived& removeOnFinish( bool doRemove ) { _item.setRemoveOnFinish( doRemove ); return self(); }

  /// Set the rate at which time advances for Motion.
  Derived& playbackSpeed( Time speed ) { _item.setPlaybackSpeed( speed ); return self(); }

  /// Set the initial time offset of the TimelineItem.
  /// For Cues, this sets the time in the future.
  /// For Motions, this is akin to adding a hold at the beginning of the Sequence.
  Derived& setStartTime( Time t ) { _item.setStartTime( t ); return self(); }

  /// Returns a shared_ptr to the control object for the Item. Allows you to cancel the Item later.
  TimelineItemControlRef  getControl() { return _item.getControl(); }

  /// Returns an object that cancels the Cue when it falls out of scope.
  /// You should store a ScopedCueRef in any class that captures [this] in a cued lambda.
  ScopedCancelRef         getScopedControl() { return std::make_shared<ScopedCancel>( _item.getControl() ); }

private:
  TimelineItem &_item;
  Derived& self() { return static_cast<Derived&>( *this ); }
};

///
/// TimelineOptions with no additional behaviors beyond base.
/// Returned when creating cues.
/// Do not store the TimelineOptions object, as it contains a non-owning reference.
///
class TimelineOptions : public TimelineOptionsBase<TimelineOptions>
{
public:
  TimelineOptions( TimelineItem &item )
  : TimelineOptionsBase<TimelineOptions>( item )
  {}
};

///
/// MotionOptions provide a temporary facade for manipulating a timeline Motion and its underlying Sequence.
/// All methods return a reference back to the MotionOptions object for chaining.
/// Do not store the MotionOptions object, as it contains non-owning references.
///
template<typename T>
class MotionOptions : public TimelineOptionsBase<MotionOptions<T>>
{
public:
  using SelfT = MotionOptions<T>;
  using MotionCallback = typename Motion<T>::Callback;

  MotionOptions( Motion<T> &motion, Sequence<T> &sequence, const Timeline &timeline ):
  TimelineOptionsBase<MotionOptions<T>>( motion ),
  _motion( motion ),
  _sequence( sequence ),
  _timeline( timeline )
  {}

  //=================================================
  // Motion Interface Mirroring.
  //=================================================

  /// Set function to be called when Motion starts. Receives reference to motion.
  SelfT& startFn( const MotionCallback &fn ) { _motion.setStartFn( fn ); return *this; }

  /// Set function to be called when Motion updates. Receives current target value.
  SelfT& updateFn( const typename Motion<T>::Callback &fn ) { _motion.setUpdateFn( fn ); return *this; }

  /// Set function to be called when Motion finishes. Receives reference to motion.
  SelfT& finishFn( const MotionCallback &fn ) { _motion.setFinishFn( fn ); return *this; }

  /// Set a function to be called when the current inflection point is crossed.
  /// An inflection occcurs when the Sequence moves from one Phrase to the next.
  /// You must add a phrase after this for the inflection to occur.
  SelfT& onInflection( const MotionCallback &fn ) { return onInflection( _sequence.getPhraseCount(), fn ); }
  /// Adds an inflection callback when the specified phrase index is crossed.
  SelfT& onInflection( size_t point, const MotionCallback &fn ) { _motion.addInflectionCallback( point, fn ); return *this; }

  /// Clip the motion in \t time from the current Motion playhead.
  /// Also discards any phrases we have already played up to this point.
  SelfT& cutIn( Time t ) { _motion.cutIn( t ); return *this; }

  /// Clip the motion at time \t from the beginning of the Motion's Sequence.
  /// When used after Timeline::apply, will have the same effect as cutIn().
  SelfT& cutAt( Time t ) { _motion.sliceSequence( 0, t ); return *this; }

  //=================================================
  // Sequence Interface Mirroring.
  //=================================================

  /// Set the current value of the Sequence. Acts as an instantaneous hold.
  SelfT& set( const T &value ) { _sequence.set( value ); return *this; }

  /// Construct and append a Phrase to the Sequence.
  template<template <typename> class PhraseT, typename... Args>
  SelfT& then( const T &value, Time duration, Args&&... args ) { _sequence.template then<PhraseT>( value, duration, std::forward<Args>(args)... ); return *this; }

  /// Append a phrase to the Sequence.
  SelfT& then( const PhraseRef<T> &phrase ) { _sequence.then( phrase ); return *this; }

  /// Append a sequence to the Sequence.
  SelfT& then( const Sequence<T> &sequence ) { _sequence.then( sequence ); return *this; }

  //=================================================
  // Extra Sugar.
  //=================================================

  /// Append a Hold to the end of the Sequence. Assumes you want to hold using the Sequence's current end value.
  SelfT& hold( Time duration ) { _sequence.template then<Hold>( _sequence.getEndValue(), duration ); return *this; }

	SelfT& holdUntil( Time time ) { _sequence.template then<Hold>( _sequence.getEndValue(), std::max<Time>( time - _sequence.getDuration(), 0 ) ); return *this; }

  //=================================================
  // Accessors to Motion and Sequence.
  //=================================================

  Sequence<T>& getSequence() { return _sequence; }
  Motion<T>&   getMotion() { return _motion; }

private:
  Motion<T>       &_motion;
  Sequence<T>     &_sequence;
  const Timeline  &_timeline;
};

} // namespace choreograph
<|endoftext|>


<commit_before>/*
Copyright 2015 Google Inc. 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.
*/

#include "stdafx.h"
#include "Utility.h"
#include <fstream>

std::vector<std::wstring> split(const std::wstring& s, char c)
{
	std::wstring::size_type i = 0;
	std::wstring::size_type j = s.find(c);

	std::vector<std::wstring> result;
	while (j != std::wstring::npos)
	{
		result.push_back(s.substr(i, j - i));
		i = ++j;
		j = s.find(c, j);
	}

	if (!s.empty())
		result.push_back(s.substr(i, s.length()));

	return result;
}

std::vector<std::wstring> GetFileList(const std::wstring& pattern, bool fullPaths)
{
	std::wstring directory;
	if (fullPaths)
	{
		const wchar_t* pFilePart = GetFilePart(pattern);
		if (pFilePart > pattern.c_str())
		{
			directory = pattern.substr(0, pFilePart - pattern.c_str());
		}
	}
	WIN32_FIND_DATA findData;
	HANDLE hFindFile = FindFirstFileEx(pattern.c_str(), FindExInfoStandard,
				&findData, FindExSearchNameMatch, NULL, 0);

	std::vector<std::wstring> result;
	if (hFindFile != INVALID_HANDLE_VALUE)
	{
		do
		{
			result.push_back(directory + findData.cFileName);
		} while (FindNextFile(hFindFile, &findData));

		FindClose(hFindFile);
	}

	return result;
}

// Load a file and convert to a string. If the file contains
// an embedded NUL then the resulting string will be truncated.
std::wstring LoadFileAsText(const std::wstring& fileName)
{
	std::ifstream f;
	f.open(fileName, std::ios_base::binary);
	if (!f)
		return L"";

	// Find the file length.
	f.seekg(0, std::ios_base::end);
	size_t length = (size_t)f.tellg();
	f.seekg(0, std::ios_base::beg);

	// Allocate a buffer and read the file.
	std::vector<char> data(length + 2);
	f.read(&data[0], length);
	if (!f)
		return L"";

	// Add a multi-byte null terminator.
	data[length] = 0;
	data[length+1] = 0;

	const wchar_t bom = 0xFEFF;
	if (memcmp(&bom, &data[0], sizeof(bom)) == 0)
	{
		// Assume UTF-16, strip bom, and return.
		return reinterpret_cast<const wchar_t*>(&data[sizeof(bom)]);
	}

	// If not-UTF-16 then convert from ANSI to wstring and return
	return AnsiToUnicode(&data[0]);
}

void WriteTextAsFile(const std::wstring& fileName, const std::wstring& text)
{
	std::ofstream outFile;
	outFile.open(fileName, std::ios_base::binary);
	if (!outFile)
		return;

	const wchar_t bom = 0xFEFF; // Always write a byte order mark
	outFile.write(reinterpret_cast<const char*>(&bom), sizeof(bom));
	outFile.write(reinterpret_cast<const char*>(text.c_str()), text.size() * sizeof(text[0]));
}

void SetRegistryDWORD(HKEY root, const std::wstring& subkey, const std::wstring& valueName, DWORD value)
{
	HKEY key;
	LONG result = RegOpenKeyEx(root, subkey.c_str(), 0, KEY_ALL_ACCESS, &key);
	if (result == ERROR_SUCCESS)
	{
		LONG setResult = RegSetValueEx(key, valueName.c_str(), 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof(value));
		RegCloseKey(key);
	}
}

void CreateRegistryKey(HKEY root, const std::wstring& subkey, const std::wstring& newKey)
{
	HKEY key;
	LONG result = RegOpenKeyEx(root, subkey.c_str(), 0, KEY_ALL_ACCESS, &key);
	if (result == ERROR_SUCCESS)
	{
		HKEY resultKey;
		result = RegCreateKey(key, newKey.c_str(), &resultKey);
		if (result == ERROR_SUCCESS)
		{
			RegCloseKey(resultKey);
		}
		RegCloseKey(key);
	}
}

std::wstring GetEditControlText(HWND hEdit)
{
	std::wstring result;
	int length = GetWindowTextLength(hEdit);
	std::vector<wchar_t> buffer(length + 1);
	GetWindowText(hEdit, &buffer[0], buffer.size());
	// Double-verify that the buffer is null-terminated.
	buffer[buffer.size() - 1] = 0;
	return &buffer[0];
}

std::wstring AnsiToUnicode(const std::string& text)
{
	// Determine number of wide characters to be allocated for the
	// Unicode string.
	size_t cCharacters = text.size() + 1;

	std::vector<wchar_t> buffer(cCharacters);

	// Convert to Unicode.
	std::wstring result;
	if (MultiByteToWideChar(CP_ACP, 0, text.c_str(), cCharacters, &buffer[0], cCharacters))
	{
		// Double-verify that the buffer is null-terminated.
		buffer[buffer.size() - 1] = 0;
		result = &buffer[0];
		return result;
	}

	return result;
}

// Get the next/previous dialog item (next/prev in window order and tab order) allowing
// for disabled controls, invisible controls, and wrapping at the end of the tab order.

static bool ControlOK(HWND win)
{
	if (!win)
		return false;
	if (!IsWindowEnabled(win))
		return false;
	if (!(GetWindowLong(win, GWL_STYLE) & WS_TABSTOP))
		return false;
	// You have to check for visibility of the parent window because during dialog
	// creation the parent window is invisible, which renders the child windows
	// all invisible - not good.
	if (!IsWindowVisible(win) && IsWindowVisible(GetParent(win)))
		return false;
	return true;
}

static HWND GetNextDlgItem(HWND win, bool Wrap)
{
	HWND next = GetWindow(win, GW_HWNDNEXT);
	while (next != win && !ControlOK(next))
	{
		if (next)
			next = GetWindow(next, GW_HWNDNEXT);
		else
		{
			if (Wrap)
				next = GetWindow(win, GW_HWNDFIRST);
			else
				return 0;
		}
	}
	assert(!Wrap || next);
	return next;
}

void SmartEnableWindow(HWND Win, BOOL Enable)
{
	assert(Win);
	if (!Enable)
	{
		HWND hasfocus = GetFocus();
		bool FocusProblem = false;
		HWND focuscopy;
		for (focuscopy = hasfocus; focuscopy; focuscopy = (GetParent)(focuscopy))
			if (focuscopy == Win)
				FocusProblem = true;
		if (FocusProblem)
		{
			HWND nextctrl = GetNextDlgItem(Win, true);
			if (nextctrl)
				SetFocus(nextctrl);
		}
	}
	::EnableWindow(Win, Enable);
}

const wchar_t* GetFilePart(const std::wstring& path)
{
	const wchar_t* pLastSlash = wcsrchr(path.c_str(), '\\');
	if (pLastSlash)
		return pLastSlash + 1;
	// If there's no slash then the file part is the entire string.
	return path.c_str();
}

const wchar_t* GetFileExt(const std::wstring& path)
{
	const wchar_t* pFilePart = GetFilePart(path);
	const wchar_t* pLastPeriod = wcsrchr(pFilePart, '.');
	if (pLastPeriod)
		return pLastPeriod;
	return pFilePart + wcslen(pFilePart);
}

const std::pair<std::wstring, std::wstring> CrackFilePart(const std::wstring& path)
{
	std::wstring filePart = GetFilePart(path);
	const std::wstring extension = GetFileExt(filePart);
	if (!extension.empty())
	{
		filePart = filePart.substr(0, filePart.size() - extension.size());
	}

	return std::pair<std::wstring, std::wstring>(filePart, extension);
}

int DeleteOneFile(HWND hwnd, const std::wstring& path)
{
	std::vector<std::wstring> paths;
	paths.push_back(path);
	return DeleteFiles(hwnd, paths);
}

int DeleteFiles(HWND hwnd, const std::vector<std::wstring>& paths)
{
	std::vector<wchar_t> fileNames;
	for (auto& path : paths)
	{
		// Push the file name and its NULL terminator onto the vector.
		fileNames.insert(fileNames.end(), path.c_str(), path.c_str() + path.size());
		fileNames.push_back(0);
	}

	// Double null-terminate.
	fileNames.push_back(0);

	SHFILEOPSTRUCT fileOp =
	{
		hwnd,
		FO_DELETE,
		&fileNames[0],
		NULL,
		FOF_ALLOWUNDO | FOF_FILESONLY | FOF_NOCONFIRMATION,
	};
	// Delete using the recycle bin.
	int result = SHFileOperation(&fileOp);

	return result;
}

void SetClipboardText(const std::wstring& text)
{
	BOOL cb = OpenClipboard(GetDesktopWindow());
	if (!cb)
		return;

	EmptyClipboard();

	size_t length = (text.size() + 1) * sizeof(wchar_t);
	HANDLE hmem = GlobalAlloc(GMEM_MOVEABLE, length);
	if (hmem)
	{
		void *ptr = GlobalLock(hmem);
		if (ptr != NULL)
		{
			memcpy(ptr, text.c_str(), length);
			GlobalUnlock(hmem);

			SetClipboardData(CF_UNICODETEXT, hmem);
		}
	}

	CloseClipboard();
}

int64_t GetFileSize(const std::wstring& path)
{
	LARGE_INTEGER result;
	HANDLE hFile = CreateFile(path.c_str(), GENERIC_READ,
		FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
		return 0;

	if (GetFileSizeEx(hFile, &result))
	{
		CloseHandle(hFile);
		return result.QuadPart;
	}
	CloseHandle(hFile);
	return 0;
}

bool Is64BitWindows()
{
	// http://blogs.msdn.com/b/oldnewthing/archive/2005/02/01/364563.aspx
	BOOL f64 = FALSE;
	bool bIsWin64 = IsWow64Process(GetCurrentProcess(), &f64) && f64;
	return bIsWin64;
}

WindowsVersion GetWindowsVersion()
{
	OSVERSIONINFO verInfo = { sizeof(OSVERSIONINFO) };
#pragma warning(suppress : 4996)	// warning C4996: 'GetVersionExA': was declared deprecated
	GetVersionEx(&verInfo);

	// Windows 10 preview has major version 10, if you have a compatibility
	// manifest for that OS, which this program should have.
	if (verInfo.dwMajorVersion > 6)
		return kWindowsVersion10;	// Or higher, I guess.

	// Windows 8.1 will only be returned if there is an appropriate
	// compatibility manifest.
	if (verInfo.dwMajorVersion == 6 && verInfo.dwMinorVersion >= 3)
		return kWindowsVersion8_1;

	if (verInfo.dwMajorVersion == 6 && verInfo.dwMinorVersion >= 2)
		return kWindowsVersion8;

	if (verInfo.dwMajorVersion == 6 && verInfo.dwMinorVersion >= 1)
		return kWindowsVersion7;

	if (verInfo.dwMajorVersion == 6)
		return kWindowsVersionVista;

	return kWindowsVersionXP;
}

bool IsWindowsServer()
{
	OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, { 0 }, 0, 0, 0, VER_NT_WORKSTATION };
	DWORDLONG        const dwlConditionMask = VerSetConditionMask(0, VER_PRODUCT_TYPE, VER_EQUAL);

	bool result = !VerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, dwlConditionMask);
	return result;
}

std::wstring FindPython()
{
#pragma warning(suppress:4996)
	const wchar_t* path = _wgetenv(L"path");
	if (path)
	{
		std::vector<std::wstring> pathParts = split(path, ';');
		for (auto part : pathParts)
		{
			std::wstring pythonPath = part + L"\\python.exe";
			if (PathFileExists(pythonPath.c_str()))
			{
				return pythonPath;
			}
		}
	}
	// No python found.
	return L"";
}
<commit_msg>Make sure UIforETW builds cleanly under /analyze.<commit_after>/*
Copyright 2015 Google Inc. 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.
*/

#include "stdafx.h"
#include "Utility.h"
#include <fstream>

std::vector<std::wstring> split(const std::wstring& s, char c)
{
	std::wstring::size_type i = 0;
	std::wstring::size_type j = s.find(c);

	std::vector<std::wstring> result;
	while (j != std::wstring::npos)
	{
		result.push_back(s.substr(i, j - i));
		i = ++j;
		j = s.find(c, j);
	}

	if (!s.empty())
		result.push_back(s.substr(i, s.length()));

	return result;
}

std::vector<std::wstring> GetFileList(const std::wstring& pattern, bool fullPaths)
{
	std::wstring directory;
	if (fullPaths)
	{
		const wchar_t* pFilePart = GetFilePart(pattern);
		if (pFilePart > pattern.c_str())
		{
			directory = pattern.substr(0, pFilePart - pattern.c_str());
		}
	}
	WIN32_FIND_DATA findData;
	HANDLE hFindFile = FindFirstFileEx(pattern.c_str(), FindExInfoStandard,
				&findData, FindExSearchNameMatch, NULL, 0);

	std::vector<std::wstring> result;
	if (hFindFile != INVALID_HANDLE_VALUE)
	{
		do
		{
			result.push_back(directory + findData.cFileName);
		} while (FindNextFile(hFindFile, &findData));

		FindClose(hFindFile);
	}

	return result;
}

// Load a file and convert to a string. If the file contains
// an embedded NUL then the resulting string will be truncated.
std::wstring LoadFileAsText(const std::wstring& fileName)
{
	std::ifstream f;
	f.open(fileName, std::ios_base::binary);
	if (!f)
		return L"";

	// Find the file length.
	f.seekg(0, std::ios_base::end);
	size_t length = (size_t)f.tellg();
	f.seekg(0, std::ios_base::beg);

	// Allocate a buffer and read the file.
	std::vector<char> data(length + 2);
	f.read(&data[0], length);
	if (!f)
		return L"";

	// Add a multi-byte null terminator.
	data[length] = 0;
	data[length+1] = 0;

	const wchar_t bom = 0xFEFF;
	if (memcmp(&bom, &data[0], sizeof(bom)) == 0)
	{
		// Assume UTF-16, strip bom, and return.
		return reinterpret_cast<const wchar_t*>(&data[sizeof(bom)]);
	}

	// If not-UTF-16 then convert from ANSI to wstring and return
	return AnsiToUnicode(&data[0]);
}

void WriteTextAsFile(const std::wstring& fileName, const std::wstring& text)
{
	std::ofstream outFile;
	outFile.open(fileName, std::ios_base::binary);
	if (!outFile)
		return;

	const wchar_t bom = 0xFEFF; // Always write a byte order mark
	outFile.write(reinterpret_cast<const char*>(&bom), sizeof(bom));
	outFile.write(reinterpret_cast<const char*>(text.c_str()), text.size() * sizeof(text[0]));
}

void SetRegistryDWORD(HKEY root, const std::wstring& subkey, const std::wstring& valueName, DWORD value)
{
	HKEY key;
	LONG result = RegOpenKeyEx(root, subkey.c_str(), 0, KEY_ALL_ACCESS, &key);
	if (result == ERROR_SUCCESS)
	{
		LONG setResult = RegSetValueEx(key, valueName.c_str(), 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof(value));
		RegCloseKey(key);
	}
}

void CreateRegistryKey(HKEY root, const std::wstring& subkey, const std::wstring& newKey)
{
	HKEY key;
	LONG result = RegOpenKeyEx(root, subkey.c_str(), 0, KEY_ALL_ACCESS, &key);
	if (result == ERROR_SUCCESS)
	{
		HKEY resultKey;
		result = RegCreateKey(key, newKey.c_str(), &resultKey);
		if (result == ERROR_SUCCESS)
		{
			RegCloseKey(resultKey);
		}
		RegCloseKey(key);
	}
}

std::wstring GetEditControlText(HWND hEdit)
{
	std::wstring result;
	int length = GetWindowTextLength(hEdit);
	std::vector<wchar_t> buffer(length + 1);
	GetWindowText(hEdit, &buffer[0], buffer.size());
	// Double-verify that the buffer is null-terminated.
	buffer[buffer.size() - 1] = 0;
	return &buffer[0];
}

std::wstring AnsiToUnicode(const std::string& text)
{
	// Determine number of wide characters to be allocated for the
	// Unicode string.
	size_t cCharacters = text.size() + 1;

	std::vector<wchar_t> buffer(cCharacters);

	// Convert to Unicode.
	std::wstring result;
	if (MultiByteToWideChar(CP_ACP, 0, text.c_str(), cCharacters, &buffer[0], cCharacters))
	{
		// Double-verify that the buffer is null-terminated.
		buffer[buffer.size() - 1] = 0;
		result = &buffer[0];
		return result;
	}

	return result;
}

// Get the next/previous dialog item (next/prev in window order and tab order) allowing
// for disabled controls, invisible controls, and wrapping at the end of the tab order.

static bool ControlOK(HWND win)
{
	if (!win)
		return false;
	if (!IsWindowEnabled(win))
		return false;
	if (!(GetWindowLong(win, GWL_STYLE) & WS_TABSTOP))
		return false;
	// You have to check for visibility of the parent window because during dialog
	// creation the parent window is invisible, which renders the child windows
	// all invisible - not good.
	if (!IsWindowVisible(win) && IsWindowVisible(GetParent(win)))
		return false;
	return true;
}

static HWND GetNextDlgItem(HWND win, bool Wrap)
{
	HWND next = GetWindow(win, GW_HWNDNEXT);
	while (next != win && !ControlOK(next))
	{
		if (next)
			next = GetWindow(next, GW_HWNDNEXT);
		else
		{
			if (Wrap)
				next = GetWindow(win, GW_HWNDFIRST);
			else
				return 0;
		}
	}
	assert(!Wrap || next);
	return next;
}

void SmartEnableWindow(HWND Win, BOOL Enable)
{
	assert(Win);
	if (!Enable)
	{
		HWND hasfocus = GetFocus();
		bool FocusProblem = false;
		HWND focuscopy;
		for (focuscopy = hasfocus; focuscopy; focuscopy = (GetParent)(focuscopy))
			if (focuscopy == Win)
				FocusProblem = true;
		if (FocusProblem)
		{
			HWND nextctrl = GetNextDlgItem(Win, true);
			if (nextctrl)
				SetFocus(nextctrl);
		}
	}
	::EnableWindow(Win, Enable);
}

const wchar_t* GetFilePart(const std::wstring& path)
{
	const wchar_t* pLastSlash = wcsrchr(path.c_str(), '\\');
	if (pLastSlash)
		return pLastSlash + 1;
	// If there's no slash then the file part is the entire string.
	return path.c_str();
}

const wchar_t* GetFileExt(const std::wstring& path)
{
	const wchar_t* pFilePart = GetFilePart(path);
	const wchar_t* pLastPeriod = wcsrchr(pFilePart, '.');
	if (pLastPeriod)
		return pLastPeriod;
	return pFilePart + wcslen(pFilePart);
}

const std::pair<std::wstring, std::wstring> CrackFilePart(const std::wstring& path)
{
	std::wstring filePart = GetFilePart(path);
	const std::wstring extension = GetFileExt(filePart);
	if (!extension.empty())
	{
		filePart = filePart.substr(0, filePart.size() - extension.size());
	}

	return std::pair<std::wstring, std::wstring>(filePart, extension);
}

int DeleteOneFile(HWND hwnd, const std::wstring& path)
{
	std::vector<std::wstring> paths;
	paths.push_back(path);
	return DeleteFiles(hwnd, paths);
}

int DeleteFiles(HWND hwnd, const std::vector<std::wstring>& paths)
{
	std::vector<wchar_t> fileNames;
	for (auto& path : paths)
	{
		// Push the file name and its NULL terminator onto the vector.
		fileNames.insert(fileNames.end(), path.c_str(), path.c_str() + path.size());
		fileNames.push_back(0);
	}

	// Double null-terminate.
	fileNames.push_back(0);

	SHFILEOPSTRUCT fileOp =
	{
		hwnd,
		FO_DELETE,
		&fileNames[0],
		NULL,
		FOF_ALLOWUNDO | FOF_FILESONLY | FOF_NOCONFIRMATION,
	};
	// Delete using the recycle bin.
	int result = SHFileOperation(&fileOp);

	return result;
}

void SetClipboardText(const std::wstring& text)
{
	BOOL cb = OpenClipboard(GetDesktopWindow());
	if (!cb)
		return;

	EmptyClipboard();

	size_t length = (text.size() + 1) * sizeof(wchar_t);
	HANDLE hmem = GlobalAlloc(GMEM_MOVEABLE, length);
	if (hmem)
	{
		void *ptr = GlobalLock(hmem);
		if (ptr != NULL)
		{
			memcpy(ptr, text.c_str(), length);
			GlobalUnlock(hmem);

			SetClipboardData(CF_UNICODETEXT, hmem);
		}
	}

	CloseClipboard();
}

int64_t GetFileSize(const std::wstring& path)
{
	LARGE_INTEGER result;
	HANDLE hFile = CreateFile(path.c_str(), GENERIC_READ,
		FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
		return 0;

	if (GetFileSizeEx(hFile, &result))
	{
		CloseHandle(hFile);
		return result.QuadPart;
	}
	CloseHandle(hFile);
	return 0;
}

bool Is64BitWindows()
{
	// http://blogs.msdn.com/b/oldnewthing/archive/2005/02/01/364563.aspx
	BOOL f64 = FALSE;
	bool bIsWin64 = IsWow64Process(GetCurrentProcess(), &f64) && f64;
	return bIsWin64;
}

WindowsVersion GetWindowsVersion()
{
	OSVERSIONINFO verInfo = { sizeof(OSVERSIONINFO) };
	// warning C4996: 'GetVersionExA': was declared deprecated
	// warning C28159: Consider using 'IsWindows*' instead of 'GetVersionExW'.Reason : Deprecated.Use VerifyVersionInfo* or IsWindows* macros from VersionHelpers.
#pragma warning(suppress : 4996)
#pragma warning(suppress : 28159)
	GetVersionEx(&verInfo);

	// Windows 10 preview has major version 10, if you have a compatibility
	// manifest for that OS, which this program should have.
	if (verInfo.dwMajorVersion > 6)
		return kWindowsVersion10;	// Or higher, I guess.

	// Windows 8.1 will only be returned if there is an appropriate
	// compatibility manifest.
	if (verInfo.dwMajorVersion == 6 && verInfo.dwMinorVersion >= 3)
		return kWindowsVersion8_1;

	if (verInfo.dwMajorVersion == 6 && verInfo.dwMinorVersion >= 2)
		return kWindowsVersion8;

	if (verInfo.dwMajorVersion == 6 && verInfo.dwMinorVersion >= 1)
		return kWindowsVersion7;

	if (verInfo.dwMajorVersion == 6)
		return kWindowsVersionVista;

	return kWindowsVersionXP;
}

bool IsWindowsServer()
{
	OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, { 0 }, 0, 0, 0, VER_NT_WORKSTATION };
	DWORDLONG        const dwlConditionMask = VerSetConditionMask(0, VER_PRODUCT_TYPE, VER_EQUAL);

	bool result = !VerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, dwlConditionMask);
	return result;
}

std::wstring FindPython()
{
#pragma warning(suppress:4996)
	const wchar_t* path = _wgetenv(L"path");
	if (path)
	{
		std::vector<std::wstring> pathParts = split(path, ';');
		for (auto part : pathParts)
		{
			std::wstring pythonPath = part + L"\\python.exe";
			if (PathFileExists(pythonPath.c_str()))
			{
				return pythonPath;
			}
		}
	}
	// No python found.
	return L"";
}
<|endoftext|>


<commit_before>#include "dynet/param-nodes.h"

#include <limits>
#include <cmath>
#include <stdexcept>

#include "dynet/nodes-macros.h"
#include "dynet/weight-decay.h"

#ifdef HAVE_CUDA
#include "dynet/gpu-ops.h"
#endif

using namespace std;

namespace dynet {

#ifndef __CUDACC__

string ConstParameterNode::as_string(const vector<string>& arg_names) const {
  ostringstream s;
  s << "const_parameters(" << dim << ") @ " << params.get();
  return s.str();
}

Dim ConstParameterNode::dim_forward(const vector<Dim>& xs) const {
  DYNET_ASSERT(xs.size() == 0, "Failed dimension check in FUNCNAME");
  return dim;
}

string ParameterNode::as_string(const vector<string>& arg_names) const {
  ostringstream s;
  s << "parameters(" << dim << ") @ " << params.get();
  return s.str();
}

Dim ParameterNode::dim_forward(const vector<Dim>& xs) const {
  DYNET_ASSERT(xs.size() == 0, "Failed dimension check in FUNCNAME");
  return dim;
}

void ParameterNode::accumulate_grad(const Tensor& g) {
  if(params.mp != nullptr)
    params.get()->accumulate_grad(g);
  else if(lparams.mp != nullptr)
    lparams.get()->accumulate_grad(g);
  else
    DYNET_RUNTIME_ERR("ConstParameterNode has neither Parameter nor LookupParameter");
}

string InputNode::as_string(const vector<string>& arg_names) const {
  ostringstream s;
  s << "constant(" << dim << ')';
  return s.str();
}

Dim InputNode::dim_forward(const vector<Dim>& xs) const {
  return dim;
}

string SparseInputNode::as_string(const vector<string>& arg_names) const {
  ostringstream s;
  s << "sparse_constant(" << dim << ')';
  return s.str();
}

Dim SparseInputNode::dim_forward(const vector<Dim>& xs) const {
  DYNET_ARG_CHECK(ids.size() == data.size(),
                          "Mismatch between size of ids (" << ids.size() << ") and size of data (" << data.size() << ") in SparseInput");
  return dim;
}

size_t SparseInputNode::aux_storage_size() const {
  return ids.size() * (sizeof(float) + sizeof(unsigned int));
}

string ScalarInputNode::as_string(const vector<string>& arg_names) const {
  ostringstream s;
  s << "scalar_constant(" << pdata << ')';
  return s.str();
}

Dim ScalarInputNode::dim_forward(const vector<Dim>& xs) const {
  return Dim({1});
}

std::string LookupNode::autobatch_profile(const ComputationGraph & cg) const {
  ostringstream oss;
  oss << "lookup ";
  dim.print_profile(oss);
  return oss.str();
}
std::vector<bool> LookupNode::autobatch_concat(const ComputationGraph & cg) const {
  return vector<bool>();
}
Node* LookupNode::autobatch_pseudo_node(const ComputationGraph & cg,
                                        const std::vector<VariableIndex> & batch_ids) const {
  vector<unsigned> ids;
  LookupNode* ln;
  for(auto batch_id : batch_ids) {
    ln = static_cast<LookupNode*>(cg.nodes[batch_id]);
    if(ln->pindex != nullptr)
      ids.push_back(*ln->pindex);
    else
      for(auto word_id : *ln->pindices)
        ids.push_back(word_id);
  }
  return new LookupNode(ln->params, ids);
}

size_t LookupNode::aux_storage_size() const {
  return dim.bd * sizeof(unsigned);
}

string LookupNode::as_string(const vector<string>& arg_names) const {
  ostringstream s;
  s << "lookup_parameters(|x|=" << params.get()->values.size() << " --> " << dim << ") @ " << params.get();
  return s.str();
}

Dim LookupNode::dim_forward(const vector<Dim>& xs) const {
  return dim;
}

void LookupNode::accumulate_grad(const Tensor& g) {
  if(pindex) {
    params.get()->accumulate_grad(*pindex, g);
  } else {
    DYNET_ASSERT(pindices, "Have neither index nor index vector in LookupNode");
    params.get()->accumulate_grads(pindices->size(), &(*pindices)[0], (unsigned*)aux_mem, g.v);
  }
}

#endif

template<class MyDevice>
void ConstParameterNode::forward_dev_impl(const MyDevice & dev, const vector<const Tensor*>& xs, Tensor& fx) const {
  DYNET_ASSERT(xs.size() == 0, "Failed dimension check in FUNCNAME");
  if(params.mp != nullptr)
    fx.tvec().device(*dev.edevice) = params.get()->values.tvec() * params.mp->weight_decay.current_weight_decay();
  else if(lparams.mp != nullptr)
    fx.tvec().device(*dev.edevice) = lparams.get()->all_values.tvec() * lparams.mp->weight_decay.current_weight_decay();
  else
    DYNET_RUNTIME_ERR("ConstParameterNode has neither Parameter nor LookupParameter");
}

template<class MyDevice>
void ConstParameterNode::backward_dev_impl(const MyDevice & dev,
                             const vector<const Tensor*>& xs,
                             const Tensor& fx,
                             const Tensor& dEdf,
                             unsigned i,
                             Tensor& dEdxi) const {
  DYNET_RUNTIME_ERR("called backward() on arity 0 node: i = " << i);
}
DYNET_NODE_INST_DEV_IMPL(ConstParameterNode)

template<class MyDevice>
void ParameterNode::forward_dev_impl(const MyDevice & dev, const vector<const Tensor*>& xs, Tensor& fx) const {
  DYNET_ASSERT(xs.size() == 0, "Failed dimension check in FUNCNAME");
// TODO
//  if (params->not_regularized) {
//    fx.v = params->values.v;
//    return;
//  }
  if(params.mp != nullptr)
    fx.tvec().device(*dev.edevice) = params.get()->values.tvec() * params.mp->weight_decay.current_weight_decay();
  else if(lparams.mp != nullptr)
    fx.tvec().device(*dev.edevice) = lparams.get()->all_values.tvec() * lparams.mp->weight_decay.current_weight_decay();
  else
    DYNET_RUNTIME_ERR("ParameterNode has neither Parameter nor LookupParameter");
}

template<class MyDevice>
void ParameterNode::backward_dev_impl(const MyDevice & dev,
                             const vector<const Tensor*>& xs,
                             const Tensor& fx,
                             const Tensor& dEdf,
                             unsigned i,
                             Tensor& dEdxi) const {
  DYNET_RUNTIME_ERR("called backward() on arity 0 node: i = " << i);
}
DYNET_NODE_INST_DEV_IMPL(ParameterNode)

template<class MyDevice>
void InputNode::forward_dev_impl(const MyDevice & dev, const vector<const Tensor*>& xs, Tensor& fx) const {
  DYNET_ASSERT(xs.size() == 0, "Failed dimension check in FUNCNAME");
#if __CUDACC__
  cudaMemcpyAsync(fx.v, &pdata->front(), dim.size() * sizeof(float), cudaMemcpyHostToDevice);
#else
  // TODO memcpy is only necessary if pdata->front() points to an unaligned location
  // need to compute this value
  bool is_input_address_aligned = false;
  if (!is_input_address_aligned) {
    memcpy(fx.v, &pdata->front(), dim.size() * sizeof(float));
  } else {
    fx.v = const_cast<float*>(&pdata->front());
  }
#endif
}

template<class MyDevice>
void InputNode::backward_dev_impl(const MyDevice & dev,
                             const vector<const Tensor*>& xs,
                             const Tensor& fx,
                             const Tensor& dEdf,
                             unsigned i,
                             Tensor& dEdxi) const {
  DYNET_RUNTIME_ERR("called backward() on arity 0 node: i = " << i);
}
DYNET_NODE_INST_DEV_IMPL(InputNode)

std::string InputNode::autobatch_profile(const ComputationGraph & cg) const {
  return "input";
}
std::vector<bool> InputNode::autobatch_concat(const ComputationGraph & cg) const {
  return vector<bool>();
}
Node* InputNode::autobatch_pseudo_node(const ComputationGraph & cg,
                                        const std::vector<VariableIndex> & batch_ids) const {
  size_t my_size = 0;
  InputNode* sin;
  for(auto bid : batch_ids) {
    sin = static_cast<InputNode*>(cg.nodes[bid]);
    my_size += sin->pdata->size();
  }
  vector<float> values(my_size);
  size_t curr_pos = 0;
  for(auto bid : batch_ids) {
    sin = static_cast<InputNode*>(cg.nodes[bid]);
    memcpy(&values[curr_pos], &(*sin->pdata)[0], sin->pdata->size() * sizeof(float));
    curr_pos += sin->pdata->size();
  }
  DYNET_ASSERT(curr_pos == values.size(), "current position and size of values does not match");
  return new InputNode(Dim({(unsigned int)my_size}), values);
}

template<class MyDevice>
void SparseInputNode::forward_dev_impl(const MyDevice & dev, const vector<const Tensor*>& xs, Tensor& fx) const {
  DYNET_ASSERT(xs.size() == 0, "Failed dimension check in FUNCNAME");
  fx.tvec().device(*dev.edevice) = fx.tvec().constant(defdata);
#if __CUDACC__
  unsigned int* ids_ptr = (unsigned int*)aux_mem;
  float* data_ptr = (float*)(ids_ptr + ids.size());
  cudaMemcpyAsync(ids_ptr, &ids[0], ids.size() * sizeof(unsigned int), cudaMemcpyHostToDevice);
  cudaMemcpyAsync(data_ptr, &data[0], data.size() * sizeof(float), cudaMemcpyHostToDevice);
  dynet::gpu::dense_to_sparse_assign(ids.size(), ids_ptr, data_ptr, fx.v);
#else
  for(size_t i = 0; i < ids.size(); ++i)
    fx.v[ids[i]] = data[i];
#endif
}

template<class MyDevice>
void SparseInputNode::backward_dev_impl(const MyDevice & dev,
                             const vector<const Tensor*>& xs,
                             const Tensor& fx,
                             const Tensor& dEdf,
                             unsigned i,
                             Tensor& dEdxi) const {
  DYNET_RUNTIME_ERR("called backward() on arity 0 node: i = " << i);
}
DYNET_NODE_INST_DEV_IMPL(SparseInputNode)

template<class MyDevice>
void ScalarInputNode::forward_dev_impl(const MyDevice & dev, const vector<const Tensor*>& xs, Tensor& fx) const {
  DYNET_ASSERT(xs.size() == 0, "Failed dimension check in FUNCNAME");
#if __CUDACC__
  cudaMemcpyAsync(fx.v, pdata, 1 * sizeof(float), cudaMemcpyHostToDevice);
#else
  fx.v[0] = *pdata;
#endif
}

template<class MyDevice>
void ScalarInputNode::backward_dev_impl(const MyDevice & dev,
                             const vector<const Tensor*>& xs,
                             const Tensor& fx,
                             const Tensor& dEdf,
                             unsigned i,
                             Tensor& dEdxi) const {
  DYNET_RUNTIME_ERR("called backward() on arity 0 node: i = " << i);
}
DYNET_NODE_INST_DEV_IMPL(ScalarInputNode)

std::string ScalarInputNode::autobatch_profile(const ComputationGraph & cg) const {
  return "scalar_input";
}
std::vector<bool> ScalarInputNode::autobatch_concat(const ComputationGraph & cg) const {
  return vector<bool>();
}
Node* ScalarInputNode::autobatch_pseudo_node(const ComputationGraph & cg,
                                             const std::vector<VariableIndex> & batch_ids) const {
  vector<float> values(batch_ids.size());
  ScalarInputNode* sin;
  for(size_t i = 0; i < batch_ids.size(); ++i) {
    sin = static_cast<ScalarInputNode*>(cg.nodes[batch_ids[i]]);
    values[i] = *sin->pdata;
  }
  return new InputNode(Dim({1}, batch_ids.size()), values);
}

template<class MyDevice>
void LookupNode::forward_dev_impl(const MyDevice & dev, const vector<const Tensor*>& xs, Tensor& fx) const {
  DYNET_ASSERT(xs.size() == 0, "Failed dimension check in FUNCNAME");
  if(pindex) {
    DYNET_ARG_CHECK(*pindex < params.get()->values.size(),
                            "Out-of-bounds attempt to access index " << *pindex << " for LookupParameter of size " << params.get()->values.size());
    DYNET_ASSERT(fx.d.batch_elems() == 1, "Batch dimension > 1 for lookup with single index");
    fx.tvec().device(*dev.edevice) = params.get()->values[*pindex].tvec() * params.mp->weight_decay.current_weight_decay();
  } else {
    DYNET_ASSERT(pindices, "Have neither index nor index vector in LookupNode");
    DYNET_ARG_CHECK(fx.d.batch_elems() == pindices->size(),
                            "In LookupNode, in index vector size (" << pindices->size() << ") "
                            "doesn't match batch size in expressions (" << fx.d.batch_elems() << ")");
#if __CUDACC__
    CUDA_CHECK(cudaMemcpyAsync((unsigned*)aux_mem, &(*pindices)[0], fx.d.bd * sizeof(unsigned), cudaMemcpyHostToDevice));
    dynet::gpu::sparse_to_dense_block_assign_and_multiply(fx.d.bd, (unsigned*)aux_mem, fx.d.batch_size(), params.mp->weight_decay.current_weight_decay(), params.get()->all_values.v, fx.v);
#else
    for (unsigned b = 0; b < pindices->size(); ++b) {
      unsigned i = pindices->at(b);
      DYNET_ARG_CHECK(i < params.get()->values.size(),
                              "Out-of-bounds attempt to access index " << i << " for LookupParameter of size " << params.get()->values.size());
      fx.tb<2>().chip<2>(b).device(*dev.edevice) = params.get()->values[i].t<2>() * params.mp->weight_decay.current_weight_decay();
    }
#endif
  }
}

template<class MyDevice>
void LookupNode::backward_dev_impl(const MyDevice & dev,
                             const vector<const Tensor*>& xs,
                             const Tensor& fx,
                             const Tensor& dEdf,
                             unsigned i,
                             Tensor& dEdxi) const {
  DYNET_RUNTIME_ERR("called backward() on arity 0 node: i = " << i);
}
DYNET_NODE_INST_DEV_IMPL(LookupNode)

} // namespace dynet
<commit_msg>Fixed compile error<commit_after>#include "dynet/param-nodes.h"

#include <limits>
#include <cmath>
#include <stdexcept>

#include "dynet/nodes-macros.h"
#include "dynet/weight-decay.h"

#ifdef HAVE_CUDA
#include "dynet/gpu-ops.h"
#endif

using namespace std;

namespace dynet {

#ifndef __CUDACC__

string ConstParameterNode::as_string(const vector<string>& arg_names) const {
  ostringstream s;
  s << "const_parameters(" << dim << ") @ " << params.get();
  return s.str();
}

Dim ConstParameterNode::dim_forward(const vector<Dim>& xs) const {
  DYNET_ASSERT(xs.size() == 0, "Failed dimension check in FUNCNAME");
  return dim;
}

string ParameterNode::as_string(const vector<string>& arg_names) const {
  ostringstream s;
  s << "parameters(" << dim << ") @ " << params.get();
  return s.str();
}

Dim ParameterNode::dim_forward(const vector<Dim>& xs) const {
  DYNET_ASSERT(xs.size() == 0, "Failed dimension check in FUNCNAME");
  return dim;
}

void ParameterNode::accumulate_grad(const Tensor& g) {
  if(params.mp != nullptr)
    params.get()->accumulate_grad(g);
  else if(lparams.mp != nullptr)
    lparams.get()->accumulate_grad(g);
  else
    DYNET_RUNTIME_ERR("ConstParameterNode has neither Parameter nor LookupParameter");
}

string InputNode::as_string(const vector<string>& arg_names) const {
  ostringstream s;
  s << "constant(" << dim << ')';
  return s.str();
}

Dim InputNode::dim_forward(const vector<Dim>& xs) const {
  return dim;
}

std::string InputNode::autobatch_profile(const ComputationGraph & cg) const {
  return "input";
}
std::vector<bool> InputNode::autobatch_concat(const ComputationGraph & cg) const {
  return vector<bool>();
}
Node* InputNode::autobatch_pseudo_node(const ComputationGraph & cg,
                                        const std::vector<VariableIndex> & batch_ids) const {
  size_t my_size = 0;
  InputNode* sin;
  for(auto bid : batch_ids) {
    sin = static_cast<InputNode*>(cg.nodes[bid]);
    my_size += sin->pdata->size();
  }
  vector<float> values(my_size);
  size_t curr_pos = 0;
  for(auto bid : batch_ids) {
    sin = static_cast<InputNode*>(cg.nodes[bid]);
    memcpy(&values[curr_pos], &(*sin->pdata)[0], sin->pdata->size() * sizeof(float));
    curr_pos += sin->pdata->size();
  }
  DYNET_ASSERT(curr_pos == values.size(), "current position and size of values does not match");
  return new InputNode(Dim({(unsigned int)my_size}), values);
}

string SparseInputNode::as_string(const vector<string>& arg_names) const {
  ostringstream s;
  s << "sparse_constant(" << dim << ')';
  return s.str();
}

Dim SparseInputNode::dim_forward(const vector<Dim>& xs) const {
  DYNET_ARG_CHECK(ids.size() == data.size(),
                          "Mismatch between size of ids (" << ids.size() << ") and size of data (" << data.size() << ") in SparseInput");
  return dim;
}

size_t SparseInputNode::aux_storage_size() const {
  return ids.size() * (sizeof(float) + sizeof(unsigned int));
}

string ScalarInputNode::as_string(const vector<string>& arg_names) const {
  ostringstream s;
  s << "scalar_constant(" << pdata << ')';
  return s.str();
}

Dim ScalarInputNode::dim_forward(const vector<Dim>& xs) const {
  return Dim({1});
}

std::string ScalarInputNode::autobatch_profile(const ComputationGraph & cg) const {
  return "scalar_input";
}
std::vector<bool> ScalarInputNode::autobatch_concat(const ComputationGraph & cg) const {
  return vector<bool>();
}
Node* ScalarInputNode::autobatch_pseudo_node(const ComputationGraph & cg,
                                             const std::vector<VariableIndex> & batch_ids) const {
  vector<float> values(batch_ids.size());
  ScalarInputNode* sin;
  for(size_t i = 0; i < batch_ids.size(); ++i) {
    sin = static_cast<ScalarInputNode*>(cg.nodes[batch_ids[i]]);
    values[i] = *sin->pdata;
  }
  return new InputNode(Dim({1}, batch_ids.size()), values);
}

std::string LookupNode::autobatch_profile(const ComputationGraph & cg) const {
  ostringstream oss;
  oss << "lookup ";
  dim.print_profile(oss);
  return oss.str();
}
std::vector<bool> LookupNode::autobatch_concat(const ComputationGraph & cg) const {
  return vector<bool>();
}
Node* LookupNode::autobatch_pseudo_node(const ComputationGraph & cg,
                                        const std::vector<VariableIndex> & batch_ids) const {
  vector<unsigned> ids;
  LookupNode* ln;
  for(auto batch_id : batch_ids) {
    ln = static_cast<LookupNode*>(cg.nodes[batch_id]);
    if(ln->pindex != nullptr)
      ids.push_back(*ln->pindex);
    else
      for(auto word_id : *ln->pindices)
        ids.push_back(word_id);
  }
  return new LookupNode(ln->params, ids);
}

size_t LookupNode::aux_storage_size() const {
  return dim.bd * sizeof(unsigned);
}

string LookupNode::as_string(const vector<string>& arg_names) const {
  ostringstream s;
  s << "lookup_parameters(|x|=" << params.get()->values.size() << " --> " << dim << ") @ " << params.get();
  return s.str();
}

Dim LookupNode::dim_forward(const vector<Dim>& xs) const {
  return dim;
}

void LookupNode::accumulate_grad(const Tensor& g) {
  if(pindex) {
    params.get()->accumulate_grad(*pindex, g);
  } else {
    DYNET_ASSERT(pindices, "Have neither index nor index vector in LookupNode");
    params.get()->accumulate_grads(pindices->size(), &(*pindices)[0], (unsigned*)aux_mem, g.v);
  }
}

#endif

template<class MyDevice>
void ConstParameterNode::forward_dev_impl(const MyDevice & dev, const vector<const Tensor*>& xs, Tensor& fx) const {
  DYNET_ASSERT(xs.size() == 0, "Failed dimension check in FUNCNAME");
  if(params.mp != nullptr)
    fx.tvec().device(*dev.edevice) = params.get()->values.tvec() * params.mp->weight_decay.current_weight_decay();
  else if(lparams.mp != nullptr)
    fx.tvec().device(*dev.edevice) = lparams.get()->all_values.tvec() * lparams.mp->weight_decay.current_weight_decay();
  else
    DYNET_RUNTIME_ERR("ConstParameterNode has neither Parameter nor LookupParameter");
}

template<class MyDevice>
void ConstParameterNode::backward_dev_impl(const MyDevice & dev,
                             const vector<const Tensor*>& xs,
                             const Tensor& fx,
                             const Tensor& dEdf,
                             unsigned i,
                             Tensor& dEdxi) const {
  DYNET_RUNTIME_ERR("called backward() on arity 0 node: i = " << i);
}
DYNET_NODE_INST_DEV_IMPL(ConstParameterNode)

template<class MyDevice>
void ParameterNode::forward_dev_impl(const MyDevice & dev, const vector<const Tensor*>& xs, Tensor& fx) const {
  DYNET_ASSERT(xs.size() == 0, "Failed dimension check in FUNCNAME");
// TODO
//  if (params->not_regularized) {
//    fx.v = params->values.v;
//    return;
//  }
  if(params.mp != nullptr)
    fx.tvec().device(*dev.edevice) = params.get()->values.tvec() * params.mp->weight_decay.current_weight_decay();
  else if(lparams.mp != nullptr)
    fx.tvec().device(*dev.edevice) = lparams.get()->all_values.tvec() * lparams.mp->weight_decay.current_weight_decay();
  else
    DYNET_RUNTIME_ERR("ParameterNode has neither Parameter nor LookupParameter");
}

template<class MyDevice>
void ParameterNode::backward_dev_impl(const MyDevice & dev,
                             const vector<const Tensor*>& xs,
                             const Tensor& fx,
                             const Tensor& dEdf,
                             unsigned i,
                             Tensor& dEdxi) const {
  DYNET_RUNTIME_ERR("called backward() on arity 0 node: i = " << i);
}
DYNET_NODE_INST_DEV_IMPL(ParameterNode)

template<class MyDevice>
void InputNode::forward_dev_impl(const MyDevice & dev, const vector<const Tensor*>& xs, Tensor& fx) const {
  DYNET_ASSERT(xs.size() == 0, "Failed dimension check in FUNCNAME");
#if __CUDACC__
  cudaMemcpyAsync(fx.v, &pdata->front(), dim.size() * sizeof(float), cudaMemcpyHostToDevice);
#else
  // TODO memcpy is only necessary if pdata->front() points to an unaligned location
  // need to compute this value
  bool is_input_address_aligned = false;
  if (!is_input_address_aligned) {
    memcpy(fx.v, &pdata->front(), dim.size() * sizeof(float));
  } else {
    fx.v = const_cast<float*>(&pdata->front());
  }
#endif
}

template<class MyDevice>
void InputNode::backward_dev_impl(const MyDevice & dev,
                             const vector<const Tensor*>& xs,
                             const Tensor& fx,
                             const Tensor& dEdf,
                             unsigned i,
                             Tensor& dEdxi) const {
  DYNET_RUNTIME_ERR("called backward() on arity 0 node: i = " << i);
}
DYNET_NODE_INST_DEV_IMPL(InputNode)

template<class MyDevice>
void SparseInputNode::forward_dev_impl(const MyDevice & dev, const vector<const Tensor*>& xs, Tensor& fx) const {
  DYNET_ASSERT(xs.size() == 0, "Failed dimension check in FUNCNAME");
  fx.tvec().device(*dev.edevice) = fx.tvec().constant(defdata);
#if __CUDACC__
  unsigned int* ids_ptr = (unsigned int*)aux_mem;
  float* data_ptr = (float*)(ids_ptr + ids.size());
  cudaMemcpyAsync(ids_ptr, &ids[0], ids.size() * sizeof(unsigned int), cudaMemcpyHostToDevice);
  cudaMemcpyAsync(data_ptr, &data[0], data.size() * sizeof(float), cudaMemcpyHostToDevice);
  dynet::gpu::dense_to_sparse_assign(ids.size(), ids_ptr, data_ptr, fx.v);
#else
  for(size_t i = 0; i < ids.size(); ++i)
    fx.v[ids[i]] = data[i];
#endif
}

template<class MyDevice>
void SparseInputNode::backward_dev_impl(const MyDevice & dev,
                             const vector<const Tensor*>& xs,
                             const Tensor& fx,
                             const Tensor& dEdf,
                             unsigned i,
                             Tensor& dEdxi) const {
  DYNET_RUNTIME_ERR("called backward() on arity 0 node: i = " << i);
}
DYNET_NODE_INST_DEV_IMPL(SparseInputNode)

template<class MyDevice>
void ScalarInputNode::forward_dev_impl(const MyDevice & dev, const vector<const Tensor*>& xs, Tensor& fx) const {
  DYNET_ASSERT(xs.size() == 0, "Failed dimension check in FUNCNAME");
#if __CUDACC__
  cudaMemcpyAsync(fx.v, pdata, 1 * sizeof(float), cudaMemcpyHostToDevice);
#else
  fx.v[0] = *pdata;
#endif
}

template<class MyDevice>
void ScalarInputNode::backward_dev_impl(const MyDevice & dev,
                             const vector<const Tensor*>& xs,
                             const Tensor& fx,
                             const Tensor& dEdf,
                             unsigned i,
                             Tensor& dEdxi) const {
  DYNET_RUNTIME_ERR("called backward() on arity 0 node: i = " << i);
}
DYNET_NODE_INST_DEV_IMPL(ScalarInputNode)

template<class MyDevice>
void LookupNode::forward_dev_impl(const MyDevice & dev, const vector<const Tensor*>& xs, Tensor& fx) const {
  DYNET_ASSERT(xs.size() == 0, "Failed dimension check in FUNCNAME");
  if(pindex) {
    DYNET_ARG_CHECK(*pindex < params.get()->values.size(),
                            "Out-of-bounds attempt to access index " << *pindex << " for LookupParameter of size " << params.get()->values.size());
    DYNET_ASSERT(fx.d.batch_elems() == 1, "Batch dimension > 1 for lookup with single index");
    fx.tvec().device(*dev.edevice) = params.get()->values[*pindex].tvec() * params.mp->weight_decay.current_weight_decay();
  } else {
    DYNET_ASSERT(pindices, "Have neither index nor index vector in LookupNode");
    DYNET_ARG_CHECK(fx.d.batch_elems() == pindices->size(),
                            "In LookupNode, in index vector size (" << pindices->size() << ") "
                            "doesn't match batch size in expressions (" << fx.d.batch_elems() << ")");
#if __CUDACC__
    CUDA_CHECK(cudaMemcpyAsync((unsigned*)aux_mem, &(*pindices)[0], fx.d.bd * sizeof(unsigned), cudaMemcpyHostToDevice));
    dynet::gpu::sparse_to_dense_block_assign_and_multiply(fx.d.bd, (unsigned*)aux_mem, fx.d.batch_size(), params.mp->weight_decay.current_weight_decay(), params.get()->all_values.v, fx.v);
#else
    for (unsigned b = 0; b < pindices->size(); ++b) {
      unsigned i = pindices->at(b);
      DYNET_ARG_CHECK(i < params.get()->values.size(),
                              "Out-of-bounds attempt to access index " << i << " for LookupParameter of size " << params.get()->values.size());
      fx.tb<2>().chip<2>(b).device(*dev.edevice) = params.get()->values[i].t<2>() * params.mp->weight_decay.current_weight_decay();
    }
#endif
  }
}

template<class MyDevice>
void LookupNode::backward_dev_impl(const MyDevice & dev,
                             const vector<const Tensor*>& xs,
                             const Tensor& fx,
                             const Tensor& dEdf,
                             unsigned i,
                             Tensor& dEdxi) const {
  DYNET_RUNTIME_ERR("called backward() on arity 0 node: i = " << i);
}
DYNET_NODE_INST_DEV_IMPL(LookupNode)

} // namespace dynet
<|endoftext|>


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

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

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

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file state.cpp
 * @author Christoph Jentzsch <cj@ethdev.com>
 * @date 2014
 * State test functions.
 */

#include <boost/filesystem/operations.hpp>
#include <boost/test/unit_test.hpp>

#include "JsonSpiritHeaders.h"
#include <libdevcore/CommonIO.h>
#include <libethereum/CanonBlockChain.h>
#include <libethereum/State.h>
#include <libethereum/ExtVM.h>
#include <libethereum/Defaults.h>
#include <libevm/VM.h>
#include "TestHelper.h"

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

namespace dev {  namespace test {

void doStateTests(json_spirit::mValue& v, bool _fillin)
{
	processCommandLineOptions();

	for (auto& i: v.get_obj())
	{
		cerr << i.first << endl;
		mObject& o = i.second.get_obj();

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

		ImportTest importer(o, _fillin);

		State theState = importer.m_statePre;
		bytes tx = importer.m_transaction.rlp();
		bytes output;

		try
		{
			theState.execute(lastHashes(importer.m_environment.currentBlock.number), tx, &output);
		}
		catch (Exception const& _e)
		{
			cnote << "state execution did throw an exception: " << diagnostic_information(_e);
			theState.commit();
		}
		catch (std::exception const& _e)
		{
			cnote << "state execution did throw an exception: " << _e.what();
		}

		if (_fillin)
		{
#if ETH_FATDB
			importer.exportTest(output, theState);
#else
			BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("You can not fill tests when FATDB is switched off"));
#endif
		}
		else
		{
			BOOST_REQUIRE(o.count("post") > 0);
			BOOST_REQUIRE(o.count("out") > 0);

			// check output
			checkOutput(output, o);

			// check logs
			checkLog(theState.pending().size() ? theState.log(0) : LogEntries(), importer.m_environment.sub.logs);

			// check addresses
#if ETH_FATDB
			cout << "fatDB is defined\n";
			auto expectedAddrs = importer.m_statePost.addresses();
			auto resultAddrs = theState.addresses();
			for (auto& expectedPair : expectedAddrs)
			{
				auto& expectedAddr = expectedPair.first;
				auto resultAddrIt = resultAddrs.find(expectedAddr);
				if (resultAddrIt == resultAddrs.end())
					BOOST_ERROR("Missing expected address " << expectedAddr);
				else
				{
					BOOST_CHECK_MESSAGE(importer.m_statePost.balance(expectedAddr) ==  theState.balance(expectedAddr), expectedAddr << ": incorrect balance " << theState.balance(expectedAddr) << ", expected " << importer.m_statePost.balance(expectedAddr));
					BOOST_CHECK_MESSAGE(importer.m_statePost.transactionsFrom(expectedAddr) ==  theState.transactionsFrom(expectedAddr), expectedAddr << ": incorrect txCount " << theState.transactionsFrom(expectedAddr) << ", expected " << importer.m_statePost.transactionsFrom(expectedAddr));
					BOOST_CHECK_MESSAGE(importer.m_statePost.code(expectedAddr) == theState.code(expectedAddr), expectedAddr << ": incorrect code");

					checkStorage(importer.m_statePost.storage(expectedAddr), theState.storage(expectedAddr), expectedAddr);
				}
			}
			checkAddresses<map<Address, u256> >(expectedAddrs, resultAddrs);
#endif
			BOOST_CHECK_MESSAGE(theState.rootHash() == h256(o["postStateRoot"].get_str()), "wrong post state root");
		}
	}
}
} }// Namespace Close

BOOST_AUTO_TEST_SUITE(StateTests)

BOOST_AUTO_TEST_CASE(stExample)
{
	dev::test::executeTests("stExample", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stSystemOperationsTest)
{
	dev::test::executeTests("stSystemOperationsTest", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stPreCompiledContracts)
{
	dev::test::executeTests("stPreCompiledContracts", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stLogTests)
{
	dev::test::executeTests("stLogTests", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stRecursiveCreate)
{
	dev::test::executeTests("stRecursiveCreate", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stInitCodeTest)
{
	dev::test::executeTests("stInitCodeTest", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stTransactionTest)
{
	dev::test::executeTests("stTransactionTest", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stSpecialTest)
{
	dev::test::executeTests("stSpecialTest", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stRefundTest)
{
	dev::test::executeTests("stRefundTest", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stBlockHashTest)
{
	dev::test::executeTests("stBlockHashTest", "/StateTests", dev::test::doStateTests);
}

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

					   dev::test::executeTests("stQuadraticComplexityTest", "/StateTests", dev::test::doStateTests);

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

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

					   dev::test::executeTests("stMemoryStressTest", "/StateTests", dev::test::doStateTests);

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

 BOOST_AUTO_TEST_CASE(stSolidityTest)
 {
		dev::test::executeTests("stSolidityTest", "/StateTests", dev::test::doStateTests);
 }

BOOST_AUTO_TEST_CASE(stMemoryTest)
{
	   dev::test::executeTests("stMemoryTest", "/StateTests", dev::test::doStateTests);
}

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

BOOST_AUTO_TEST_CASE(userDefinedFileState)
{
	dev::test::userDefinedTest("--singletest", dev::test::doStateTests);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>add memory tests<commit_after>/*
	This file is part of cpp-ethereum.

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

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

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file state.cpp
 * @author Christoph Jentzsch <cj@ethdev.com>
 * @date 2014
 * State test functions.
 */

#include <boost/filesystem/operations.hpp>
#include <boost/test/unit_test.hpp>

#include "JsonSpiritHeaders.h"
#include <libdevcore/CommonIO.h>
#include <libethereum/CanonBlockChain.h>
#include <libethereum/State.h>
#include <libethereum/ExtVM.h>
#include <libethereum/Defaults.h>
#include <libevm/VM.h>
#include "TestHelper.h"

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

namespace dev {  namespace test {

void doStateTests(json_spirit::mValue& v, bool _fillin)
{
	processCommandLineOptions();

	for (auto& i: v.get_obj())
	{
		cerr << i.first << endl;
		mObject& o = i.second.get_obj();

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

		ImportTest importer(o, _fillin);

		State theState = importer.m_statePre;
		bytes tx = importer.m_transaction.rlp();
		bytes output;

		try
		{
			theState.execute(lastHashes(importer.m_environment.currentBlock.number), tx, &output);
		}
		catch (Exception const& _e)
		{
			cnote << "state execution did throw an exception: " << diagnostic_information(_e);
			theState.commit();
		}
		catch (std::exception const& _e)
		{
			cnote << "state execution did throw an exception: " << _e.what();
		}

		if (_fillin)
		{
#if ETH_FATDB
			importer.exportTest(output, theState);
#else
			BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("You can not fill tests when FATDB is switched off"));
#endif
		}
		else
		{
			BOOST_REQUIRE(o.count("post") > 0);
			BOOST_REQUIRE(o.count("out") > 0);

			// check output
			checkOutput(output, o);

			// check logs
			checkLog(theState.pending().size() ? theState.log(0) : LogEntries(), importer.m_environment.sub.logs);

			// check addresses
#if ETH_FATDB
			auto expectedAddrs = importer.m_statePost.addresses();
			auto resultAddrs = theState.addresses();
			for (auto& expectedPair : expectedAddrs)
			{
				auto& expectedAddr = expectedPair.first;
				auto resultAddrIt = resultAddrs.find(expectedAddr);
				if (resultAddrIt == resultAddrs.end())
					BOOST_ERROR("Missing expected address " << expectedAddr);
				else
				{
					BOOST_CHECK_MESSAGE(importer.m_statePost.balance(expectedAddr) ==  theState.balance(expectedAddr), expectedAddr << ": incorrect balance " << theState.balance(expectedAddr) << ", expected " << importer.m_statePost.balance(expectedAddr));
					BOOST_CHECK_MESSAGE(importer.m_statePost.transactionsFrom(expectedAddr) ==  theState.transactionsFrom(expectedAddr), expectedAddr << ": incorrect txCount " << theState.transactionsFrom(expectedAddr) << ", expected " << importer.m_statePost.transactionsFrom(expectedAddr));
					BOOST_CHECK_MESSAGE(importer.m_statePost.code(expectedAddr) == theState.code(expectedAddr), expectedAddr << ": incorrect code");

					checkStorage(importer.m_statePost.storage(expectedAddr), theState.storage(expectedAddr), expectedAddr);
				}
			}
			checkAddresses<map<Address, u256> >(expectedAddrs, resultAddrs);
#endif
			BOOST_CHECK_MESSAGE(theState.rootHash() == h256(o["postStateRoot"].get_str()), "wrong post state root");
		}
	}
}
} }// Namespace Close

BOOST_AUTO_TEST_SUITE(StateTests)

BOOST_AUTO_TEST_CASE(stExample)
{
	dev::test::executeTests("stExample", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stSystemOperationsTest)
{
	dev::test::executeTests("stSystemOperationsTest", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stPreCompiledContracts)
{
	dev::test::executeTests("stPreCompiledContracts", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stLogTests)
{
	dev::test::executeTests("stLogTests", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stRecursiveCreate)
{
	dev::test::executeTests("stRecursiveCreate", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stInitCodeTest)
{
	dev::test::executeTests("stInitCodeTest", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stTransactionTest)
{
	dev::test::executeTests("stTransactionTest", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stSpecialTest)
{
	dev::test::executeTests("stSpecialTest", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stRefundTest)
{
	dev::test::executeTests("stRefundTest", "/StateTests", dev::test::doStateTests);
}

BOOST_AUTO_TEST_CASE(stBlockHashTest)
{
	dev::test::executeTests("stBlockHashTest", "/StateTests", dev::test::doStateTests);
}

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

					   dev::test::executeTests("stQuadraticComplexityTest", "/StateTests", dev::test::doStateTests);

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

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

					   dev::test::executeTests("stMemoryStressTest", "/StateTests", dev::test::doStateTests);

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

 BOOST_AUTO_TEST_CASE(stSolidityTest)
 {
		dev::test::executeTests("stSolidityTest", "/StateTests", dev::test::doStateTests);
 }

BOOST_AUTO_TEST_CASE(stMemoryTest)
{
	   dev::test::executeTests("stMemoryTest", "/StateTests", dev::test::doStateTests);
}

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

BOOST_AUTO_TEST_CASE(userDefinedFileState)
{
	dev::test::userDefinedTest("--singletest", dev::test::doStateTests);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>