<commit_before>/*
 * Copyright 2014 Jose Fonseca
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

/*
 * Simple addr2line like utility.
 */

#include <assert.h>
#include <stdio.h>
#include <stdint.h>

#include <windows.h>
#include <dbghelp.h>

#include "symbols.h"

static BOOL CALLBACK
callback(HANDLE hProcess,
         ULONG ActionCode,
         ULONG64 CallbackData,
         ULONG64 UserContext)
{
    if (ActionCode == CBA_DEBUG_INFO) {
        fputs((LPCSTR)(UINT_PTR)CallbackData, stderr);
        return TRUE;
    }

    return FALSE;
}

int
main(int argc, char **argv)
{
    BOOL bRet;
    DWORD dwRet;

    if (argc < 3) {
        fprintf(stderr, "usage: %s <dll> <addr> ...\n", argv[0]);
        return 1;
    }

    // Load the module
    char *szModule = argv[1];
    HMODULE hModule = NULL;
#ifdef _WIN64
    hModule = LoadLibraryExA(szModule, NULL, LOAD_LIBRARY_AS_DATAFILE);
#endif
    if (!hModule) {
        hModule = LoadLibraryExA(szModule, NULL, DONT_RESOLVE_DLL_REFERENCES);
    }
    if (!hModule) {
        fprintf(stderr, "error: failed to load %s\n", szModule);
        return 1;
    }

    DWORD dwSymOptions = SymGetOptions();

    dwSymOptions |= SYMOPT_LOAD_LINES;

#ifndef NDEBUG
    dwSymOptions |= SYMOPT_DEBUG;
#endif

    // We can get more information by calling UnDecorateSymbolName() ourselves.
    if (0) {
        dwSymOptions |= SYMOPT_UNDNAME;
    } else {
        dwSymOptions &= ~SYMOPT_UNDNAME;
    }

    SymSetOptions(dwSymOptions);

    HANDLE hProcess = GetCurrentProcess();
    bRet = InitializeSym(hProcess, FALSE);
    assert(bRet);

    SymRegisterCallback64(hProcess, &callback, 0);

    dwRet = SymLoadModuleEx(hProcess, NULL, szModule, NULL, (DWORD64)(UINT_PTR)hModule, 0, NULL, 0);
    if (!dwRet) {
        fprintf(stderr, "error: failed to load module symbols\n");
    }

    if (!GetModuleHandleA("symsrv.dll")) {
        fprintf(stderr, "symbol server not loaded\n");
    }

    for (int i = 2; i < argc; ++i) {
        const char *arg = argv[i];
        DWORD64 dwRelAddr;
        if (arg[0] == '0' && arg[1] == 'x') {
            sscanf(&arg[2], "%08I64X", &dwRelAddr);
        } else {
            dwRelAddr = atol(arg);
        }
        printf("dwRelAddr = %08I64X\n", dwRelAddr);

        UINT_PTR dwAddr = (UINT_PTR)hModule + dwRelAddr;

        struct {
            SYMBOL_INFO Symbol;
            CHAR Name[512];
        } sym;
        ZeroMemory(&sym, sizeof sym);
        sym.Symbol.SizeOfStruct = sizeof sym.Symbol;
        sym.Symbol.MaxNameLen = sizeof sym.Symbol.Name + sizeof sym.Name;
        DWORD64 dwSymDisplacement = 0;
        bRet = SymFromAddr(hProcess, dwAddr, &dwSymDisplacement, &sym.Symbol);
        if (bRet) {
            printf("Symbol.Name = %s\n", sym.Symbol.Name);
            char UnDecoratedName[512];
            if (UnDecorateSymbolName( sym.Symbol.Name, UnDecoratedName, sizeof UnDecoratedName, UNDNAME_COMPLETE)) {
                printf("UnDecoratedName = %s\n", UnDecoratedName);
            }
        }

        IMAGEHLP_LINE64 line;
        ZeroMemory(&line, sizeof line);
        line.SizeOfStruct = sizeof line;
        DWORD dwLineDisplacement = 0;
        bRet = SymGetLineFromAddr64(hProcess, dwAddr, &dwLineDisplacement, &line);
        if (bRet) {
            printf("FileName = %s\n", line.FileName);
            printf("LineNumber = %lu\n", line.LineNumber);
        }

        printf("\n");
    }

    SymCleanup(hProcess);

    FreeLibrary(hModule);

    return 0;
}
<commit_msg>addrline: Use stdint.h macros for 64bit integers<commit_after>/*
 * Copyright 2014 Jose Fonseca
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

/*
 * Simple addr2line like utility.
 */

#define __STDC_FORMAT_MACROS 1

#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

#include <windows.h>
#include <dbghelp.h>

#include "symbols.h"

static BOOL CALLBACK
callback(HANDLE hProcess,
         ULONG ActionCode,
         ULONG64 CallbackData,
         ULONG64 UserContext)
{
    if (ActionCode == CBA_DEBUG_INFO) {
        fputs((LPCSTR)(UINT_PTR)CallbackData, stderr);
        return TRUE;
    }

    return FALSE;
}

int
main(int argc, char **argv)
{
    BOOL bRet;
    DWORD dwRet;

    if (argc < 3) {
        fprintf(stderr, "usage: %s <dll> <addr> ...\n", argv[0]);
        return 1;
    }

    // Load the module
    char *szModule = argv[1];
    HMODULE hModule = NULL;
#ifdef _WIN64
    hModule = LoadLibraryExA(szModule, NULL, LOAD_LIBRARY_AS_DATAFILE);
#endif
    if (!hModule) {
        hModule = LoadLibraryExA(szModule, NULL, DONT_RESOLVE_DLL_REFERENCES);
    }
    if (!hModule) {
        fprintf(stderr, "error: failed to load %s\n", szModule);
        return 1;
    }

    DWORD dwSymOptions = SymGetOptions();

    dwSymOptions |= SYMOPT_LOAD_LINES;

#ifndef NDEBUG
    dwSymOptions |= SYMOPT_DEBUG;
#endif

    // We can get more information by calling UnDecorateSymbolName() ourselves.
    if (0) {
        dwSymOptions |= SYMOPT_UNDNAME;
    } else {
        dwSymOptions &= ~SYMOPT_UNDNAME;
    }

    SymSetOptions(dwSymOptions);

    HANDLE hProcess = GetCurrentProcess();
    bRet = InitializeSym(hProcess, FALSE);
    assert(bRet);

    SymRegisterCallback64(hProcess, &callback, 0);

    dwRet = SymLoadModuleEx(hProcess, NULL, szModule, NULL, (DWORD64)(UINT_PTR)hModule, 0, NULL, 0);
    if (!dwRet) {
        fprintf(stderr, "error: failed to load module symbols\n");
    }

    if (!GetModuleHandleA("symsrv.dll")) {
        fprintf(stderr, "symbol server not loaded\n");
    }

    for (int i = 2; i < argc; ++i) {
        const char *arg = argv[i];
        DWORD64 dwRelAddr;
        if (arg[0] == '0' && arg[1] == 'x') {
            sscanf(&arg[2], "%08" PRIX64, &dwRelAddr);
        } else {
            dwRelAddr = atol(arg);
        }
        printf("dwRelAddr = %08" PRIX64 "\n", dwRelAddr);

        UINT_PTR dwAddr = (UINT_PTR)hModule + dwRelAddr;

        struct {
            SYMBOL_INFO Symbol;
            CHAR Name[512];
        } sym;
        ZeroMemory(&sym, sizeof sym);
        sym.Symbol.SizeOfStruct = sizeof sym.Symbol;
        sym.Symbol.MaxNameLen = sizeof sym.Symbol.Name + sizeof sym.Name;
        DWORD64 dwSymDisplacement = 0;
        bRet = SymFromAddr(hProcess, dwAddr, &dwSymDisplacement, &sym.Symbol);
        if (bRet) {
            printf("Symbol.Name = %s\n", sym.Symbol.Name);
            char UnDecoratedName[512];
            if (UnDecorateSymbolName( sym.Symbol.Name, UnDecoratedName, sizeof UnDecoratedName, UNDNAME_COMPLETE)) {
                printf("UnDecoratedName = %s\n", UnDecoratedName);
            }
        }

        IMAGEHLP_LINE64 line;
        ZeroMemory(&line, sizeof line);
        line.SizeOfStruct = sizeof line;
        DWORD dwLineDisplacement = 0;
        bRet = SymGetLineFromAddr64(hProcess, dwAddr, &dwLineDisplacement, &line);
        if (bRet) {
            printf("FileName = %s\n", line.FileName);
            printf("LineNumber = %lu\n", line.LineNumber);
        }

        printf("\n");
    }

    SymCleanup(hProcess);

    FreeLibrary(hModule);

    return 0;
}
<|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 "canary_control.h"

#include "messages.h"
#include "model_util.h"

namespace devtools {
namespace cdbg {

// Number of attempts to register or approve a canary breakpoint before
// failing the operation.
static constexpr int kMaxAttempts = 3;

// The "ApproveHealtyBreakpoints" method is called from worker thread every
// cycle of "ListActiveBreakpoints", which is once every 40 seconds. The
// constant of 35 seconds is deliberately a bit shorter than that so that the
// canary period fits in one such cycle.
DEFINE_int32(
    min_canary_duration_ms,
    35000,
    "Time interval after which an enabled canary breakpoint is considered as "
    "safe for a global rollout (from this debuglet's perspective)");

CanaryControl::CanaryControl(
    CallbacksMonitor* callbacks_monitor,
    Bridge* bridge)
    : callbacks_monitor_(callbacks_monitor),
      bridge_(bridge) {
}

bool CanaryControl::RegisterBreakpointCanary(
    const string& breakpoint_id,
    std::function<void(std::unique_ptr<StatusMessageModel>)> fn_complete) {
  int64 current_timestamp_ms = callbacks_monitor_->GetCurrentTimeMillis();

  {
    MutexLock lock(&mu_);
    // Fail if already in canary.
    if (canary_breakpoints_.find(breakpoint_id) != canary_breakpoints_.end()) {
      LOG(ERROR) << "Breakpoint " << breakpoint_id
                 << " already registered for canary";
      DCHECK(false);
      return false;
    }

    // Optimistically mark the breakpoint as if in canary. We don't want to
    // keep the mutex locked throughout the call to the backend.
    canary_breakpoints_[breakpoint_id] = { current_timestamp_ms, fn_complete };
  }

  for (int attempt = 0; attempt < kMaxAttempts; ++attempt) {
    if (bridge_->RegisterBreakpointCanary(breakpoint_id)) {
      return true;
    }
  }

  // Roll back the marking that the breakpoint is in canary.
  MutexLock lock(&mu_);
  canary_breakpoints_.erase(breakpoint_id);

  return false;
}

void CanaryControl::BreakpointCompleted(const string& breakpoint_id) {
  MutexLock lock(&mu_);
  canary_breakpoints_.erase(breakpoint_id);
}

void CanaryControl::ApproveHealtyBreakpoints() {
  // Choose breakpoints that can be approved.
  std::vector<string> healthy_ids;
  std::map<string, CanaryBreakpoint> unhealthy_ids;
  {
    int64 current_timestamp_ms = callbacks_monitor_->GetCurrentTimeMillis();
    int64 cutoff = current_timestamp_ms - FLAGS_min_canary_duration_ms;

    MutexLock lock(&mu_);
    for (const auto& entry : canary_breakpoints_) {
      if (entry.second.register_time > cutoff) {
        continue;  // The breakpoint hasn't spent enough time in canary.
      }

      // Declare the canary breakpoint as benign if there are no stuck
      // callbacks.
      if (callbacks_monitor_->IsHealthy(entry.second.register_time)) {
        healthy_ids.push_back(entry.first);
        continue;
      }

      LOG(WARNING) << "Long or stuck callbacks detected during canary "
                      " breakpoint period " << entry.first;
      unhealthy_ids.emplace(entry);
    }
  }

  // Try to approve the breakpoints.
  std::vector<string> approved_ids;
  approved_ids.reserve(healthy_ids.size());

  for (const string& breakpoint_id : healthy_ids) {
    for (int attempt = 0; attempt < kMaxAttempts; ++attempt) {
      if (bridge_->ApproveBreakpointCanary(breakpoint_id)) {
        approved_ids.push_back(breakpoint_id);
        break;
      }
    }
  }

  // Complete unhealthy breakpoints.
  for (const auto& entry : unhealthy_ids) {
    entry.second.fn_complete(StatusMessageBuilder()
        .set_error()
        .set_format(CanaryBreakpointUnhealthy)
        .build());
  }

  MutexLock lock(&mu_);

  // Remove the approved breakpoints from the canary list.
  for (const string& breakpoint_id : approved_ids) {
    canary_breakpoints_.erase(breakpoint_id);
  }

  // We may have some unhealthy breakpoints. They have are now completed, and
  // "JvmBreakpointsManager" will call "BreakpointCompleted", so we don't
  // really have to erase them from "canary_breakpoints_". We still do it
  // just to be on the safe side.
  for (const auto& entry : unhealthy_ids) {
    canary_breakpoints_.erase(entry.first);
  }
}

}  // namespace cdbg
}  // namespace devtools

<commit_msg>A fix to opensource Java agent build. On GCE debian VM images, we have gcc 4.7.2 installed, which doesn't support std::map::emplace (added in gcc 4.8.0). ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=120961642<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 "canary_control.h"

#include "messages.h"
#include "model_util.h"

namespace devtools {
namespace cdbg {

// Number of attempts to register or approve a canary breakpoint before
// failing the operation.
static constexpr int kMaxAttempts = 3;

// The "ApproveHealtyBreakpoints" method is called from worker thread every
// cycle of "ListActiveBreakpoints", which is once every 40 seconds. The
// constant of 35 seconds is deliberately a bit shorter than that so that the
// canary period fits in one such cycle.
DEFINE_int32(
    min_canary_duration_ms,
    35000,
    "Time interval after which an enabled canary breakpoint is considered as "
    "safe for a global rollout (from this debuglet's perspective)");

CanaryControl::CanaryControl(
    CallbacksMonitor* callbacks_monitor,
    Bridge* bridge)
    : callbacks_monitor_(callbacks_monitor),
      bridge_(bridge) {
}

bool CanaryControl::RegisterBreakpointCanary(
    const string& breakpoint_id,
    std::function<void(std::unique_ptr<StatusMessageModel>)> fn_complete) {
  int64 current_timestamp_ms = callbacks_monitor_->GetCurrentTimeMillis();

  {
    MutexLock lock(&mu_);
    // Fail if already in canary.
    if (canary_breakpoints_.find(breakpoint_id) != canary_breakpoints_.end()) {
      LOG(ERROR) << "Breakpoint " << breakpoint_id
                 << " already registered for canary";
      DCHECK(false);
      return false;
    }

    // Optimistically mark the breakpoint as if in canary. We don't want to
    // keep the mutex locked throughout the call to the backend.
    canary_breakpoints_[breakpoint_id] = { current_timestamp_ms, fn_complete };
  }

  for (int attempt = 0; attempt < kMaxAttempts; ++attempt) {
    if (bridge_->RegisterBreakpointCanary(breakpoint_id)) {
      return true;
    }
  }

  // Roll back the marking that the breakpoint is in canary.
  MutexLock lock(&mu_);
  canary_breakpoints_.erase(breakpoint_id);

  return false;
}

void CanaryControl::BreakpointCompleted(const string& breakpoint_id) {
  MutexLock lock(&mu_);
  canary_breakpoints_.erase(breakpoint_id);
}

void CanaryControl::ApproveHealtyBreakpoints() {
  // Choose breakpoints that can be approved.
  std::vector<string> healthy_ids;
  std::map<string, CanaryBreakpoint> unhealthy_ids;
  {
    int64 current_timestamp_ms = callbacks_monitor_->GetCurrentTimeMillis();
    int64 cutoff = current_timestamp_ms - FLAGS_min_canary_duration_ms;

    MutexLock lock(&mu_);
    for (const auto& entry : canary_breakpoints_) {
      if (entry.second.register_time > cutoff) {
        continue;  // The breakpoint hasn't spent enough time in canary.
      }

      // Declare the canary breakpoint as benign if there are no stuck
      // callbacks.
      if (callbacks_monitor_->IsHealthy(entry.second.register_time)) {
        healthy_ids.push_back(entry.first);
        continue;
      }

      LOG(WARNING) << "Long or stuck callbacks detected during canary "
                      " breakpoint period " << entry.first;
      unhealthy_ids[entry.first] = entry.second;
    }
  }

  // Try to approve the breakpoints.
  std::vector<string> approved_ids;
  approved_ids.reserve(healthy_ids.size());

  for (const string& breakpoint_id : healthy_ids) {
    for (int attempt = 0; attempt < kMaxAttempts; ++attempt) {
      if (bridge_->ApproveBreakpointCanary(breakpoint_id)) {
        approved_ids.push_back(breakpoint_id);
        break;
      }
    }
  }

  // Complete unhealthy breakpoints.
  for (const auto& entry : unhealthy_ids) {
    entry.second.fn_complete(StatusMessageBuilder()
        .set_error()
        .set_format(CanaryBreakpointUnhealthy)
        .build());
  }

  MutexLock lock(&mu_);

  // Remove the approved breakpoints from the canary list.
  for (const string& breakpoint_id : approved_ids) {
    canary_breakpoints_.erase(breakpoint_id);
  }

  // We may have some unhealthy breakpoints. They have are now completed, and
  // "JvmBreakpointsManager" will call "BreakpointCompleted", so we don't
  // really have to erase them from "canary_breakpoints_". We still do it
  // just to be on the safe side.
  for (const auto& entry : unhealthy_ids) {
    canary_breakpoints_.erase(entry.first);
  }
}

}  // namespace cdbg
}  // namespace devtools

<|endoftext|>


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

#include "scriptingcomponent.h"
#include "scriptingcomponentprivate.h"
#include "scriptingengine.h"

#include "game.h"
#include "gameobject.h"
#include "scene.h"
#include <qscriptclass.h>
#include <qscriptvalueiterator.h>
#include <core/messagehandler.h>

REGISTER_OBJECTTYPE( GluonEngine, ScriptingComponent )

using namespace GluonEngine;

ScriptingComponent::ScriptingComponent( QObject* parent )
    : Component( parent )
    , d( new ScriptingComponentPrivate(this) )
{
}

ScriptingComponent::~ScriptingComponent()
{
    delete d;
}

QString
ScriptingComponent::category() const
{
    return QString( "Game Logic" );
}

ScriptingAsset* ScriptingComponent::script() const
{
    return d->scriptingAsset;
}

void ScriptingComponent::setScript( GluonEngine::ScriptingAsset* newAsset )
{
	if(d->scriptingAsset)
        disconnect(d->scriptingAsset, SIGNAL(dataChanged()), this, SLOT(scriptAssetUpdated()));

    d->scriptingAsset = newAsset;
    connect(newAsset, SIGNAL(dataChanged()), this, SLOT(scriptAssetUpdated()));
}

void ScriptingComponent::scriptAssetUpdated()
{
    d->updateScriptObject();
}

QScriptValue ScriptingComponent::scriptObject()
{
    return d->scriptObject;
}

void ScriptingComponent::initialize()
{
	if(!d->scriptingAsset)
		return;

	if(!d->scriptingAsset->isLoaded())
		d->scriptingAsset->load();

	if(!d->scriptingAsset->isLoaded())
		return;

	if(!d->scriptObject.isValid())
	{
		d->updateScriptObject();
	}

    if( !d->scriptObject.isValid() )
        debug( "Warning: No scripting asset has been chosen" );

    if( d->initializeFunction.isFunction() )
    {
        d->initializeFunction.call( d->scriptObject );
        if( ScriptingEngine::instance()->scriptEngine()->uncaughtException().isValid() )
            // This needs to be mapped...
            debug( QString( "%1: %2" )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtException().toString() )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtExceptionBacktrace().join( " " ) ) );
    }
    GluonEngine::Component::initialize();
}

void ScriptingComponent::start()
{
    if( d->startFunction.isFunction() )
    {
        d->startFunction.call( d->scriptObject );
        if( ScriptingEngine::instance()->scriptEngine()->uncaughtException().isValid() )
            // This needs to be mapped...
            debug( QString( "%1: %2" )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtException().toString() )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtExceptionBacktrace().join( " " ) ) );
    }
    GluonEngine::Component::start();
}

void ScriptingComponent::update( int elapsedMilliseconds )
{
    if( d->updateFunction.isFunction() )
    {
        d->updateFunction.call( d->scriptObject, QScriptValueList() << elapsedMilliseconds );
        if( ScriptingEngine::instance()->scriptEngine()->uncaughtException().isValid() )
            // This needs to be mapped...
            debug( QString( "%1: %2" )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtException().toString() )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtExceptionBacktrace().join( " " ) ) );
    }
    GluonEngine::Component::update( elapsedMilliseconds );
}

void ScriptingComponent::draw( int timeLapse )
{
    if( d->drawFunction.isFunction() )
    {
        d->drawFunction.call( d->scriptObject, QScriptValueList() << timeLapse );
        if( ScriptingEngine::instance()->scriptEngine()->uncaughtException().isValid() )
            // This needs to be mapped...
            debug( QString( "%1: %2" )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtException().toString() )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtExceptionBacktrace().join( " " ) ) );
    }
    GluonEngine::Component::draw();
}

void ScriptingComponent::stop()
{
    if( d->stopFunction.isFunction() )
    {
        d->stopFunction.call( d->scriptObject );
        if( ScriptingEngine::instance()->scriptEngine()->uncaughtException().isValid() )
            // This needs to be mapped...
            debug( QString( "%1: %2" )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtException().toString() )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtExceptionBacktrace().join( " " ) ) );
    }
    GluonEngine::Component::stop();
}

void ScriptingComponent::cleanup()
{
    if( d->cleanupFunction.isFunction() )
    {
        d->cleanupFunction.call( d->scriptObject );
        if( ScriptingEngine::instance()->scriptEngine()->uncaughtException().isValid() )
            // This needs to be mapped...
            debug( QString( "%1: %2" )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtException().toString() )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtExceptionBacktrace().join( " " ) ) );
    }
    GluonEngine::Component::cleanup();
}

#include "scriptingcomponent.moc"
<commit_msg>If we have an exception in update or draw, don't keep running it<commit_after>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2010 Dan Leinir Turthra Jensen <admin@leinir.dk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "scriptingcomponent.h"
#include "scriptingcomponentprivate.h"
#include "scriptingengine.h"

#include "game.h"
#include "gameobject.h"
#include "scene.h"
#include <qscriptclass.h>
#include <qscriptvalueiterator.h>
#include <core/messagehandler.h>

REGISTER_OBJECTTYPE( GluonEngine, ScriptingComponent )

using namespace GluonEngine;

ScriptingComponent::ScriptingComponent( QObject* parent )
    : Component( parent )
    , d( new ScriptingComponentPrivate(this) )
{
}

ScriptingComponent::~ScriptingComponent()
{
    delete d;
}

QString
ScriptingComponent::category() const
{
    return QString( "Game Logic" );
}

ScriptingAsset* ScriptingComponent::script() const
{
    return d->scriptingAsset;
}

void ScriptingComponent::setScript( GluonEngine::ScriptingAsset* newAsset )
{
	if(d->scriptingAsset)
        disconnect(d->scriptingAsset, SIGNAL(dataChanged()), this, SLOT(scriptAssetUpdated()));

    d->scriptingAsset = newAsset;
    connect(newAsset, SIGNAL(dataChanged()), this, SLOT(scriptAssetUpdated()));
}

void ScriptingComponent::scriptAssetUpdated()
{
    d->updateScriptObject();
}

QScriptValue ScriptingComponent::scriptObject()
{
    return d->scriptObject;
}

void ScriptingComponent::initialize()
{
	if(!d->scriptingAsset)
		return;

	if(!d->scriptingAsset->isLoaded())
		d->scriptingAsset->load();

	if(!d->scriptingAsset->isLoaded())
		return;

	if(!d->scriptObject.isValid())
	{
		d->updateScriptObject();
	}

    if( !d->scriptObject.isValid() )
        debug( "Warning: No scripting asset has been chosen" );

    if( d->initializeFunction.isFunction() )
    {
        d->initializeFunction.call( d->scriptObject );
        if( ScriptingEngine::instance()->scriptEngine()->uncaughtException().isValid() )
            debug( QString( "%1: %2" )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtException().toString() )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtExceptionBacktrace().join( " " ) ) );
    }
    GluonEngine::Component::initialize();
}

void ScriptingComponent::start()
{
    if( d->startFunction.isFunction() )
    {
        d->startFunction.call( d->scriptObject );
        if( ScriptingEngine::instance()->scriptEngine()->uncaughtException().isValid() )
        {
            debug( QString( "%1: %2" )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtException().toString() )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtExceptionBacktrace().join( " " ) ) );
        }
    }
    GluonEngine::Component::start();
}

void ScriptingComponent::update( int elapsedMilliseconds )
{
    if( d->updateFunction.isFunction() )
    {
        d->updateFunction.call( d->scriptObject, QScriptValueList() << elapsedMilliseconds );
        if( ScriptingEngine::instance()->scriptEngine()->uncaughtException().isValid() )
        {
            d->updateFunction = QScriptValue();
            debug( QString( "%1: %2" )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtException().toString() )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtExceptionBacktrace().join( " " ) ) );
        }
    }
    GluonEngine::Component::update( elapsedMilliseconds );
}

void ScriptingComponent::draw( int timeLapse )
{
    if( d->drawFunction.isFunction() )
    {
        d->drawFunction.call( d->scriptObject, QScriptValueList() << timeLapse );
        if( ScriptingEngine::instance()->scriptEngine()->uncaughtException().isValid() )
        {
            d->drawFunction = QScriptValue();
            debug( QString( "%1: %2" )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtException().toString() )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtExceptionBacktrace().join( " " ) ) );
        }
    }
    GluonEngine::Component::draw();
}

void ScriptingComponent::stop()
{
    if( d->stopFunction.isFunction() )
    {
        d->stopFunction.call( d->scriptObject );
        if( ScriptingEngine::instance()->scriptEngine()->uncaughtException().isValid() )
            debug( QString( "%1: %2" )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtException().toString() )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtExceptionBacktrace().join( " " ) ) );
    }
    GluonEngine::Component::stop();
}

void ScriptingComponent::cleanup()
{
    if( d->cleanupFunction.isFunction() )
    {
        d->cleanupFunction.call( d->scriptObject );
        if( ScriptingEngine::instance()->scriptEngine()->uncaughtException().isValid() )
            debug( QString( "%1: %2" )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtException().toString() )
                   .arg( ScriptingEngine::instance()->scriptEngine()->uncaughtExceptionBacktrace().join( " " ) ) );
    }
    GluonEngine::Component::cleanup();
}

#include "scriptingcomponent.moc"
<|endoftext|>


<commit_before><commit_msg>fix dodgy assigns to const array param<commit_after><|endoftext|>


<commit_before>// Copyright (2015) Gustav

#include "finans/core/commandline.h"

#include "gtest/gtest.h"
#include "gmock/gmock.h"

using namespace testing;

struct CommandlineTest : public Test {
  std::ostringstream output;
  std::ostringstream error;
};

#define GTEST(x) TEST_F(CommandlineTest, x)

/*
void main(int argc, char* argv[])
{
  enum MyEnum
  {
    MyVal, MyVal2
  };

  std::string compiler;
  int i;
  int op = 2;
  std::vector<std::string> strings;
  //MyEnum v;
  bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    ("compiler", compiler)
    ("int", i)
    ("-op", op)
    .add<std::vector<std::string>, std::string>("-strings", strings, argparse::Extra().count(argparse::Count::MoreThanOne).metavar("string"), argparse::PushBackVector<std::string>) // todo: is this beautifiable?
    //("-enum", &v, Convert<MyEnum>("MyVal", MyEnum::MyVal)("MyVal2", MyEnum::MyVal2) )
    .parseArgs(argc, argv);
  if (ok == false) return;
  std::cout << compiler << " " << i << " " << op << std::endl;
  BOOST_FOREACH(const std::string& s, strings)
  {
    std::cout << s << " " << std::endl;
  }
}
*/

GTEST(TestEmpty) {
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    .ParseArgs(argparse::Arguments("app.exe", {}), output, error);
  EXPECT_EQ(true, ok);
}

GTEST(TestError) {
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    .ParseArgs(argparse::Arguments("app.exe", { "hello", "world" }), output, error);
  EXPECT_EQ(false, ok);
}

GTEST(TestOptionalDefault) {
  int op = 2;
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    ("-op", op)
    .ParseArgs(argparse::Arguments("app.exe", {}), output, error);
  EXPECT_EQ(true, ok);
  EXPECT_EQ(2, op);
}

GTEST(TestOptionalValue) {
  int op = 2;
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    ("-op", op)
    .ParseArgs(argparse::Arguments("app.exe", {"-op", "42"}), output, error);
  EXPECT_EQ(true, ok);
  EXPECT_EQ(42, op);
}

GTEST(TestPositionalValue) {
  int op = 2;
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    ("op", op)
    .ParseArgs(argparse::Arguments("app.exe", { "42" }), output, error);
  EXPECT_EQ(true, ok);
  EXPECT_EQ(42, op);
}

GTEST(TestPositionalValueErr) {
  int op = 42;
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    ("op", op)
    .ParseArgs(argparse::Arguments("app.exe", {}), output, error);
  EXPECT_EQ(false, ok);
  EXPECT_EQ(42, op); // not touched
}

GTEST(TestStdVector) {
  std::vector<std::string> strings;
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    .AddGreedy("-strings", strings, "string")
    .ParseArgs(argparse::Arguments("app.exe", {"-strings", "cat", "dog", "fish"}), output, error);
  EXPECT_EQ(true, ok);
  EXPECT_THAT(strings, ElementsAre("cat", "dog", "fish"));
}

GTEST(TestStdVectorInts) {
  std::vector<int> ints;
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    .AddGreedy("-ints", ints, "string")
    .ParseArgs(argparse::Arguments("app.exe", { "-ints", "2", "3", "-5", "4" }), output, error);
  EXPECT_EQ(true, ok);
  EXPECT_THAT(ints, ElementsAre(2, 3, -5, 4));
}

GTEST(TestnonGreedyVector) {
  std::vector<std::string> strings;
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    ("-s", strings)
    .ParseArgs(argparse::Arguments("app.exe", { "-s", "cat", "-s", "dog", "-s", "fish" }), output, error);
  EXPECT_EQ(true, ok);
  EXPECT_THAT(strings, ElementsAre("cat", "dog", "fish"));
}<commit_msg>fixed spelling error<commit_after>// Copyright (2015) Gustav

#include "finans/core/commandline.h"

#include "gtest/gtest.h"
#include "gmock/gmock.h"

using namespace testing;

struct CommandlineTest : public Test {
  std::ostringstream output;
  std::ostringstream error;
};

#define GTEST(x) TEST_F(CommandlineTest, x)

/*
void main(int argc, char* argv[])
{
  enum MyEnum
  {
    MyVal, MyVal2
  };

  std::string compiler;
  int i;
  int op = 2;
  std::vector<std::string> strings;
  //MyEnum v;
  bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    ("compiler", compiler)
    ("int", i)
    ("-op", op)
    .add<std::vector<std::string>, std::string>("-strings", strings, argparse::Extra().count(argparse::Count::MoreThanOne).metavar("string"), argparse::PushBackVector<std::string>) // todo: is this beautifiable?
    //("-enum", &v, Convert<MyEnum>("MyVal", MyEnum::MyVal)("MyVal2", MyEnum::MyVal2) )
    .parseArgs(argc, argv);
  if (ok == false) return;
  std::cout << compiler << " " << i << " " << op << std::endl;
  BOOST_FOREACH(const std::string& s, strings)
  {
    std::cout << s << " " << std::endl;
  }
}
*/

GTEST(TestEmpty) {
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    .ParseArgs(argparse::Arguments("app.exe", {}), output, error);
  EXPECT_EQ(true, ok);
}

GTEST(TestError) {
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    .ParseArgs(argparse::Arguments("app.exe", { "hello", "world" }), output, error);
  EXPECT_EQ(false, ok);
}

GTEST(TestOptionalDefault) {
  int op = 2;
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    ("-op", op)
    .ParseArgs(argparse::Arguments("app.exe", {}), output, error);
  EXPECT_EQ(true, ok);
  EXPECT_EQ(2, op);
}

GTEST(TestOptionalValue) {
  int op = 2;
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    ("-op", op)
    .ParseArgs(argparse::Arguments("app.exe", {"-op", "42"}), output, error);
  EXPECT_EQ(true, ok);
  EXPECT_EQ(42, op);
}

GTEST(TestPositionalValue) {
  int op = 2;
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    ("op", op)
    .ParseArgs(argparse::Arguments("app.exe", { "42" }), output, error);
  EXPECT_EQ(true, ok);
  EXPECT_EQ(42, op);
}

GTEST(TestPositionalValueErr) {
  int op = 42;
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    ("op", op)
    .ParseArgs(argparse::Arguments("app.exe", {}), output, error);
  EXPECT_EQ(false, ok);
  EXPECT_EQ(42, op); // not touched
}

GTEST(TestStdVector) {
  std::vector<std::string> strings;
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    .AddGreedy("-strings", strings, "string")
    .ParseArgs(argparse::Arguments("app.exe", {"-strings", "cat", "dog", "fish"}), output, error);
  EXPECT_EQ(true, ok);
  EXPECT_THAT(strings, ElementsAre("cat", "dog", "fish"));
}

GTEST(TestStdVectorInts) {
  std::vector<int> ints;
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    .AddGreedy("-ints", ints, "string")
    .ParseArgs(argparse::Arguments("app.exe", { "-ints", "2", "3", "-5", "4" }), output, error);
  EXPECT_EQ(true, ok);
  EXPECT_THAT(ints, ElementsAre(2, 3, -5, 4));
}

GTEST(TestNonGreedyVector) {
  std::vector<std::string> strings;
  const bool ok = argparse::Parser::ParseComplete ==
    argparse::Parser("description")
    ("-s", strings)
    .ParseArgs(argparse::Arguments("app.exe", { "-s", "cat", "-s", "dog", "-s", "fish" }), output, error);
  EXPECT_EQ(true, ok);
  EXPECT_THAT(strings, ElementsAre("cat", "dog", "fish"));
}
<|endoftext|>


<commit_before>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//
// Contributors: Sven Kaulmann

#ifndef DUNE_STUFF_GRID_ENTITY_VISUALIZATION_HH
#define DUNE_STUFF_GRID_ENTITY_VISUALIZATION_HH

#include <dune/stuff/common/filesystem.hh>
#include <dune/stuff/aliases.hh>
#include <dune/stuff/common/ranges.hh>
#include <dune/geometry/genericgeometry/referenceelements.hh>
#include <dune/grid/common/mcmgmapper.hh>
#include <dune/stuff/common/disable_warnings.hh>
# include <dune/grid/io/file/vtk/vtkwriter.hh>
# include <dune/grid/io/file/dgfparser/dgfparser.hh>
#include <dune/stuff/common/reenable_warnings.hh>

namespace Dune {
namespace Stuff {
namespace Grid {

struct ElementVisualization {
    //! Parameter for mapper class
    template<int dim>
    struct P0Layout
    {
      bool contains (const Dune::GeometryType& gt)
      {
        if (gt.dim()==dim) return true;
        return false;
      }
    };

    // demonstrate attaching data to elements
    template<class Grid, class F>
    static void elementdata (const Grid& grid, const F& f)
    {
      // get grid view on leaf part
      const auto gridView = grid.leafView();

      // make a mapper for codim 0 entities in the leaf grid
      Dune::LeafMultipleCodimMultipleGeomTypeMapper<Grid,P0Layout>
          mapper(grid);

      std::vector<double> values(mapper.size());
      for (const auto& entity : DSC::viewRange(gridView))
      {
        values[mapper.map(entity)] = f(entity);
      }

      Dune::VTKWriter<typename Grid::LeafGridView> vtkwriter(gridView);
      vtkwriter.addCellData(values,"data");
      const std::string piecefilesFolderName = "piecefiles";
      const std::string piecefilesPath = f.dir() + "/" + piecefilesFolderName + "/";
      DSC::testCreateDirectory( piecefilesPath );
      vtkwriter.pwrite( f.filename(), f.dir(), piecefilesFolderName, Dune::VTK::appendedraw);
    }

    class FunctorBase {
        public:
            FunctorBase ( const std::string fname,
                          const std::string dname)
                : filename_(fname)
                , dir_(dname)
            {}
            const std::string filename() const { return filename_; }
            const std::string dir() const { return dir_; }
        protected:
            const std::string filename_;
            const std::string dir_;

    };

    class VolumeFunctor : public FunctorBase {
        public:
            VolumeFunctor ( const std::string fname,
                            const std::string dname)
                : FunctorBase(fname, dname) {}

            template <class Entity>
            double operator() ( const Entity& ent ) const
            {
                return ent.geometry().volume();
            }
    };

    class ProcessIdFunctor : public FunctorBase {
        public:
            ProcessIdFunctor ( const std::string fname,
                               const std::string dname )
                : FunctorBase(fname, dname)
            {}

            template <class Entity>
            double operator() ( const Entity& /*ent*/ ) const
            {
                return Dune::MPIHelper::getCollectiveCommunication().rank();
            }
    };

    template < class GridType >
    class BoundaryFunctor : public FunctorBase {
        const GridType& grid_;
        public:
            BoundaryFunctor ( const GridType& grid,
                              const std::string fname,
                              const std::string dname)
                : FunctorBase(fname, dname)
                , grid_(grid)
            {}

            template <class Entity>
            double operator() ( const Entity& entity ) const
            {
                double ret( 0.0 );
                int numberOfBoundarySegments( 0 );
                bool isOnBoundary = false;
                const auto leafview = grid_.leafView();
                for ( const auto& intersection : DSC::intersectionRange(leafview, entity) )
                {
                    if ( !intersection.neighbor() && intersection.boundary() ) {
                        isOnBoundary = true;
                        numberOfBoundarySegments += 1;
                        ret += double( intersection.boundaryId() );
                    }
                }
                if ( isOnBoundary ) {
                    ret /= double( numberOfBoundarySegments );
                }
                return ret;
            }
    };

    class AreaMarker : public FunctorBase {

        public:
            AreaMarker( const std::string fname,
                        const std::string dname)
                : FunctorBase(fname, dname) {}

            template <class Entity>
            double operator() ( const Entity& entity ) const
            {
                typedef typename Entity::Geometry
                EntityGeometryType;

                typedef Dune::FieldVector< typename EntityGeometryType::ctype, EntityGeometryType::coorddimension>
                DomainType;

                const EntityGeometryType& geometry = entity.geometry();

                DomainType baryCenter( 0.0 );

                for ( int corner = 0; corner < geometry.corners(); ++corner ) {
                    baryCenter += geometry.corner( corner );
                }
                baryCenter /= geometry.corners();

                double ret( 0.0 );

                if ( !( ( baryCenter[0] < 0.0 ) || ( baryCenter[0] > 1.0 ) ) ) { // only in unit square
                    if ( !( ( baryCenter[1] < 0.0 ) || ( baryCenter[1] > 1.0 ) ) ) {
                        ret = 1.0;
                    }
                }
                return ret;
            }
    };

    class GeometryFunctor : public FunctorBase {
        public:
            GeometryFunctor ( const std::string fname,
                              const std::string dname)
                : FunctorBase(fname, dname) {}

            template <class Entity>
            double operator() ( const Entity& ent ) const
            {
                const typename Entity::Geometry& geo = ent.geometry();
                double vol = geo.volume();
                if ( vol < 0 ) {
                    std::cout << std::setiosflags( std::ios::fixed ) << std::setprecision( 6 ) << std::setw( 8 );
                    //std::cout.showpoint();
                    for ( int i = 0; i < geo.corners(); ++i ) {
                        std::cout << geo.corner( i ) << "\t\t" ;
                    }
                    std::cout << std::endl;
                }
                return vol;
            }
    };

    //! supply functor
    template<class Grid>
    static void all( const Grid& grid,
              const std::string outputDir = "visualisation")
    {
        // make function objects
        BoundaryFunctor<Grid> boundaryFunctor(grid, "boundaryFunctor", outputDir);
        AreaMarker areaMarker("areaMarker", outputDir);
        GeometryFunctor geometryFunctor("geometryFunctor", outputDir);
        ProcessIdFunctor processIdFunctor("ProcessIdFunctor", outputDir);
        VolumeFunctor volumeFunctor("volumeFunctor", outputDir);

        // call the visualization functions
        elementdata( grid, boundaryFunctor );
        elementdata( grid, areaMarker );
        elementdata( grid, geometryFunctor );
        elementdata( grid, processIdFunctor );
        elementdata( grid, volumeFunctor );
    }
};

} //namespace Stuff
} //namespace Grid
} //namespace Dune

#endif // DUNE_STUFF_GRID_ENTITY_VISUALIZATION_HH
<commit_msg>[grid.output.entity_visualization] disable warnings<commit_after>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//
// Contributors: Sven Kaulmann

#ifndef DUNE_STUFF_GRID_ENTITY_VISUALIZATION_HH
#define DUNE_STUFF_GRID_ENTITY_VISUALIZATION_HH

#include <dune/stuff/common/filesystem.hh>
#include <dune/stuff/aliases.hh>
#include <dune/stuff/common/ranges.hh>
#include <dune/geometry/genericgeometry/referenceelements.hh>
#include <dune/stuff/common/disable_warnings.hh>
# include <dune/grid/common/mcmgmapper.hh>
# include <dune/grid/io/file/vtk/vtkwriter.hh>
# include <dune/grid/io/file/dgfparser/dgfparser.hh>
#include <dune/stuff/common/reenable_warnings.hh>

namespace Dune {
namespace Stuff {
namespace Grid {

struct ElementVisualization {
    //! Parameter for mapper class
    template<int dim>
    struct P0Layout
    {
      bool contains (const Dune::GeometryType& gt)
      {
        if (gt.dim()==dim) return true;
        return false;
      }
    };

    // demonstrate attaching data to elements
    template<class Grid, class F>
    static void elementdata (const Grid& grid, const F& f)
    {
      // get grid view on leaf part
      const auto gridView = grid.leafView();

      // make a mapper for codim 0 entities in the leaf grid
      Dune::LeafMultipleCodimMultipleGeomTypeMapper<Grid,P0Layout>
          mapper(grid);

      std::vector<double> values(mapper.size());
      for (const auto& entity : DSC::viewRange(gridView))
      {
        values[mapper.map(entity)] = f(entity);
      }

      Dune::VTKWriter<typename Grid::LeafGridView> vtkwriter(gridView);
      vtkwriter.addCellData(values,"data");
      const std::string piecefilesFolderName = "piecefiles";
      const std::string piecefilesPath = f.dir() + "/" + piecefilesFolderName + "/";
      DSC::testCreateDirectory( piecefilesPath );
      vtkwriter.pwrite( f.filename(), f.dir(), piecefilesFolderName, Dune::VTK::appendedraw);
    }

    class FunctorBase {
        public:
            FunctorBase ( const std::string fname,
                          const std::string dname)
                : filename_(fname)
                , dir_(dname)
            {}
            const std::string filename() const { return filename_; }
            const std::string dir() const { return dir_; }
        protected:
            const std::string filename_;
            const std::string dir_;

    };

    class VolumeFunctor : public FunctorBase {
        public:
            VolumeFunctor ( const std::string fname,
                            const std::string dname)
                : FunctorBase(fname, dname) {}

            template <class Entity>
            double operator() ( const Entity& ent ) const
            {
                return ent.geometry().volume();
            }
    };

    class ProcessIdFunctor : public FunctorBase {
        public:
            ProcessIdFunctor ( const std::string fname,
                               const std::string dname )
                : FunctorBase(fname, dname)
            {}

            template <class Entity>
            double operator() ( const Entity& /*ent*/ ) const
            {
                return Dune::MPIHelper::getCollectiveCommunication().rank();
            }
    };

    template < class GridType >
    class BoundaryFunctor : public FunctorBase {
        const GridType& grid_;
        public:
            BoundaryFunctor ( const GridType& grid,
                              const std::string fname,
                              const std::string dname)
                : FunctorBase(fname, dname)
                , grid_(grid)
            {}

            template <class Entity>
            double operator() ( const Entity& entity ) const
            {
                double ret( 0.0 );
                int numberOfBoundarySegments( 0 );
                bool isOnBoundary = false;
                const auto leafview = grid_.leafView();
                for ( const auto& intersection : DSC::intersectionRange(leafview, entity) )
                {
                    if ( !intersection.neighbor() && intersection.boundary() ) {
                        isOnBoundary = true;
                        numberOfBoundarySegments += 1;
                        ret += double( intersection.boundaryId() );
                    }
                }
                if ( isOnBoundary ) {
                    ret /= double( numberOfBoundarySegments );
                }
                return ret;
            }
    };

    class AreaMarker : public FunctorBase {

        public:
            AreaMarker( const std::string fname,
                        const std::string dname)
                : FunctorBase(fname, dname) {}

            template <class Entity>
            double operator() ( const Entity& entity ) const
            {
                typedef typename Entity::Geometry
                EntityGeometryType;

                typedef Dune::FieldVector< typename EntityGeometryType::ctype, EntityGeometryType::coorddimension>
                DomainType;

                const EntityGeometryType& geometry = entity.geometry();

                DomainType baryCenter( 0.0 );

                for ( int corner = 0; corner < geometry.corners(); ++corner ) {
                    baryCenter += geometry.corner( corner );
                }
                baryCenter /= geometry.corners();

                double ret( 0.0 );

                if ( !( ( baryCenter[0] < 0.0 ) || ( baryCenter[0] > 1.0 ) ) ) { // only in unit square
                    if ( !( ( baryCenter[1] < 0.0 ) || ( baryCenter[1] > 1.0 ) ) ) {
                        ret = 1.0;
                    }
                }
                return ret;
            }
    };

    class GeometryFunctor : public FunctorBase {
        public:
            GeometryFunctor ( const std::string fname,
                              const std::string dname)
                : FunctorBase(fname, dname) {}

            template <class Entity>
            double operator() ( const Entity& ent ) const
            {
                const typename Entity::Geometry& geo = ent.geometry();
                double vol = geo.volume();
                if ( vol < 0 ) {
                    std::cout << std::setiosflags( std::ios::fixed ) << std::setprecision( 6 ) << std::setw( 8 );
                    //std::cout.showpoint();
                    for ( int i = 0; i < geo.corners(); ++i ) {
                        std::cout << geo.corner( i ) << "\t\t" ;
                    }
                    std::cout << std::endl;
                }
                return vol;
            }
    };

    //! supply functor
    template<class Grid>
    static void all( const Grid& grid,
              const std::string outputDir = "visualisation")
    {
        // make function objects
        BoundaryFunctor<Grid> boundaryFunctor(grid, "boundaryFunctor", outputDir);
        AreaMarker areaMarker("areaMarker", outputDir);
        GeometryFunctor geometryFunctor("geometryFunctor", outputDir);
        ProcessIdFunctor processIdFunctor("ProcessIdFunctor", outputDir);
        VolumeFunctor volumeFunctor("volumeFunctor", outputDir);

        // call the visualization functions
        elementdata( grid, boundaryFunctor );
        elementdata( grid, areaMarker );
        elementdata( grid, geometryFunctor );
        elementdata( grid, processIdFunctor );
        elementdata( grid, volumeFunctor );
    }
};

} //namespace Stuff
} //namespace Grid
} //namespace Dune

#endif // DUNE_STUFF_GRID_ENTITY_VISUALIZATION_HH
<|endoftext|>


<commit_before>#pragma once

#include <sstream>
#include <type_traits>

#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>

#include <reflectionzeug/Property.h>

namespace
{

template <typename T, unsigned Count>
std::string toString(const T * data)
{
    std::stringstream ss;

    ss << "(";

    for (unsigned i = 0; i < Count; ++i)
    {
        if (i > 0)
            ss << ", ";

        ss << data[i];
    }

    ss << ")";

    return ss.str();
}

template <typename T, unsigned Count>
bool fromString(const std::string & string, T * data)
{
    std::string elementRegex = std::is_integral<T>::value ? "(-|\\+)?\\d+" : "(-|\\+)?\\d+\\.?\\d*";

    std::stringstream ss;
    ss << "\\s*\\(";
    for (unsigned i=0; i<Count-1; ++i)
    {
        ss << "(" << elementRegex << ")";
        ss << "\\s*,\\s*";
    }
    ss << elementRegex << "\\)\\s*";

    if (!reflectionzeug::util::matchesRegex(string, ss.str()))
        return false;

    std::vector<std::string> parts = reflectionzeug::util::extract(string, elementRegex);

    assert(parts.size() == Count);

    for (unsigned i = 0; i < Count; ++i)
    {
        const std::string & part = parts[i];
        data[i] = std::is_integral<T>::value ? static_cast<T>(std::stoi(part)) : static_cast<T>(std::stod(part));
    }

    return true;
}

class Vec2Property : public reflectionzeug::ValueProperty<glm::vec2>
{
public:
    using Type = glm::vec2;

public:
    template <typename... Arguments>
    Vec2Property::Vec2Property(Arguments&&... args)
    :   ValueProperty<glm::vec2>(std::forward<Arguments>(args)...) {}

    virtual std::string toString() const override
    {
        return ::toString<glm::vec2::value_type, 2>(glm::value_ptr(this->value()));
    }

    virtual bool fromString(const std::string & string) override
    {
        glm::vec2 value;
        if (!::fromString<glm::vec2::value_type, 2>(string, glm::value_ptr(value)))
            return false;

        setValue(value);
        return true;
    }
};

template <>
class IVec2Property : public reflectionzeug::ValueProperty<glm::ivec2>
{
public:
    using Type = glm::ivec2;

public:
    template <typename... Arguments>
    IVec2Property::IVec2Property(Arguments&&... args)
    :   ValueProperty<glm::ivec2>(std::forward<Arguments>(args)...) {}

    virtual std::string toString() const override
    {
        return ::toString<glm::ivec2::value_type, 2>(glm::value_ptr(value()));
    }

    virtual bool fromString(const std::string & string) override
    {
        glm::ivec2 value;
        if (!::fromString<glm::ivec2::value_type, 2>(string, glm::value_ptr(value)))
            return false;

        setValue(value);
        return true;
    }
};

template <>
class Vec3Property : public ValueProperty<glm::vec3>
{
public:
    using Type = glm::vec3;

public:
    template <typename... Arguments>
    Vec3Property::Vec3Property(Arguments&&... args)
    :   ValueProperty<glm::vec3>(std::forward<Arguments>(args)...) {}

    virtual std::string toString() const override
    {
        return ::toString<glm::vec3::value_type, 3>(glm::value_ptr(value()));
    }

    virtual bool fromString(const std::string & string) override
    {
        glm::vec3 value;
        if (!::fromString<glm::vec3::value_type, 3>(string, glm::value_ptr(value)))
            return false;

        setValue(value);
        return true;
    }
};

template <>
class Vec4Property : public ValueProperty<glm::vec4>
{
public:
    using Type = glm::vec4;

public:
    template <typename... Arguments>
    Vec4Property::Vec4Property(Arguments&&... args)
    :   ValueProperty<glm::vec4>(std::forward<Arguments>(args)...) {}

    virtual std::string toString() const override
    {
        return ::toString<glm::vec4::value_type, 4>(glm::value_ptr(value()));
    }

    virtual bool fromString(const std::string & string) override
    {
        glm::vec4 value;
        if (!::fromString<glm::vec4::value_type, 4>(string, glm::value_ptr(value)))
            return false;

        setValue(value);
        return true;
    }
};

} // namespace

namespace reflectionzeug
{

template <>
struct PropertyClass<typename Vec2Property::Type>
{
    using Type = Vec2Property;
};

template <>
struct PropertyClass<typename IVec2Property::Type>
{
    using Type = IVec2Property;
};

template <>
struct PropertyClass<typename Vec3Property::Type>
{
    using Type = Vec3Property;
};

template <>
struct PropertyClass<typename Vec4Property::Type>
{
    using Type = Vec4Property;
};

} // namespace reflectionzeug
<commit_msg>remove unnecessary typename<commit_after>#pragma once

#include <sstream>
#include <type_traits>

#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>

#include <reflectionzeug/Property.h>

namespace
{

template <typename T, unsigned Count>
std::string toString(const T * data)
{
    std::stringstream ss;

    ss << "(";

    for (unsigned i = 0; i < Count; ++i)
    {
        if (i > 0)
            ss << ", ";

        ss << data[i];
    }

    ss << ")";

    return ss.str();
}

template <typename T, unsigned Count>
bool fromString(const std::string & string, T * data)
{
    std::string elementRegex = std::is_integral<T>::value ? "(-|\\+)?\\d+" : "(-|\\+)?\\d+\\.?\\d*";

    std::stringstream ss;
    ss << "\\s*\\(";
    for (unsigned i=0; i<Count-1; ++i)
    {
        ss << "(" << elementRegex << ")";
        ss << "\\s*,\\s*";
    }
    ss << elementRegex << "\\)\\s*";

    if (!reflectionzeug::util::matchesRegex(string, ss.str()))
        return false;

    std::vector<std::string> parts = reflectionzeug::util::extract(string, elementRegex);

    assert(parts.size() == Count);

    for (unsigned i = 0; i < Count; ++i)
    {
        const std::string & part = parts[i];
        data[i] = std::is_integral<T>::value ? static_cast<T>(std::stoi(part)) : static_cast<T>(std::stod(part));
    }

    return true;
}

class Vec2Property : public reflectionzeug::ValueProperty<glm::vec2>
{
public:
    using Type = glm::vec2;

public:
    template <typename... Arguments>
    Vec2Property::Vec2Property(Arguments&&... args)
    :   ValueProperty<glm::vec2>(std::forward<Arguments>(args)...) {}

    virtual std::string toString() const override
    {
        return ::toString<glm::vec2::value_type, 2>(glm::value_ptr(this->value()));
    }

    virtual bool fromString(const std::string & string) override
    {
        glm::vec2 value;
        if (!::fromString<glm::vec2::value_type, 2>(string, glm::value_ptr(value)))
            return false;

        setValue(value);
        return true;
    }
};

template <>
class IVec2Property : public reflectionzeug::ValueProperty<glm::ivec2>
{
public:
    using Type = glm::ivec2;

public:
    template <typename... Arguments>
    IVec2Property::IVec2Property(Arguments&&... args)
    :   ValueProperty<glm::ivec2>(std::forward<Arguments>(args)...) {}

    virtual std::string toString() const override
    {
        return ::toString<glm::ivec2::value_type, 2>(glm::value_ptr(value()));
    }

    virtual bool fromString(const std::string & string) override
    {
        glm::ivec2 value;
        if (!::fromString<glm::ivec2::value_type, 2>(string, glm::value_ptr(value)))
            return false;

        setValue(value);
        return true;
    }
};

template <>
class Vec3Property : public ValueProperty<glm::vec3>
{
public:
    using Type = glm::vec3;

public:
    template <typename... Arguments>
    Vec3Property::Vec3Property(Arguments&&... args)
    :   ValueProperty<glm::vec3>(std::forward<Arguments>(args)...) {}

    virtual std::string toString() const override
    {
        return ::toString<glm::vec3::value_type, 3>(glm::value_ptr(value()));
    }

    virtual bool fromString(const std::string & string) override
    {
        glm::vec3 value;
        if (!::fromString<glm::vec3::value_type, 3>(string, glm::value_ptr(value)))
            return false;

        setValue(value);
        return true;
    }
};

template <>
class Vec4Property : public ValueProperty<glm::vec4>
{
public:
    using Type = glm::vec4;

public:
    template <typename... Arguments>
    Vec4Property::Vec4Property(Arguments&&... args)
    :   ValueProperty<glm::vec4>(std::forward<Arguments>(args)...) {}

    virtual std::string toString() const override
    {
        return ::toString<glm::vec4::value_type, 4>(glm::value_ptr(value()));
    }

    virtual bool fromString(const std::string & string) override
    {
        glm::vec4 value;
        if (!::fromString<glm::vec4::value_type, 4>(string, glm::value_ptr(value)))
            return false;

        setValue(value);
        return true;
    }
};

} // namespace

namespace reflectionzeug
{

template <>
struct PropertyClass<Vec2Property::Type>
{
    using Type = Vec2Property;
};

template <>
struct PropertyClass<IVec2Property::Type>
{
    using Type = IVec2Property;
};

template <>
struct PropertyClass<Vec3Property::Type>
{
    using Type = Vec3Property;
};

template <>
struct PropertyClass<Vec4Property::Type>
{
    using Type = Vec4Property;
};

} // namespace reflectionzeug
<|endoftext|>


<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

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 "paddle/framework/executor.h"

#include <set>

#include "gflags/gflags.h"
#include "paddle/framework/feed_fetch_method.h"
#include "paddle/framework/feed_fetch_type.h"
#include "paddle/framework/lod_rank_table.h"
#include "paddle/framework/lod_tensor_array.h"
#include "paddle/framework/op_registry.h"
#include "paddle/platform/place.h"
#include "paddle/platform/profiler.h"

DECLARE_bool(do_memory_benchmark);
DEFINE_bool(check_nan_inf, false,
            "Checking whether operator produce NAN/INF or not. It will be "
            "extremely slow so please use this flag wisely.");

namespace paddle {
namespace framework {

const std::string kFeedOpType = "feed";
const std::string kFetchOpType = "fetch";

Executor::Executor(const platform::Place& place) : place_(place) {}

static void CreateTensor(Variable* var, proto::VarDesc::VarType var_type) {
  if (var_type == proto::VarDesc::LOD_TENSOR) {
    var->GetMutable<LoDTensor>();
  } else if (var_type == proto::VarDesc::SELECTED_ROWS) {
    var->GetMutable<SelectedRows>();
  } else if (var_type == proto::VarDesc::FEED_MINIBATCH) {
    var->GetMutable<FeedFetchList>();
  } else if (var_type == proto::VarDesc::FETCH_LIST) {
    var->GetMutable<FeedFetchList>();
  } else if (var_type == proto::VarDesc::STEP_SCOPES) {
    var->GetMutable<std::vector<framework::Scope>>();
  } else if (var_type == proto::VarDesc::LOD_RANK_TABLE) {
    var->GetMutable<LoDRankTable>();
  } else if (var_type == proto::VarDesc::LOD_TENSOR_ARRAY) {
    var->GetMutable<LoDTensorArray>();
  } else if (var_type == proto::VarDesc::PLACE_LIST) {
    var->GetMutable<platform::PlaceList>();
  } else {
    PADDLE_THROW(
        "Variable type %d is not in "
        "[LoDTensor, SelectedRows, FEED_MINIBATCH, FETCH_LIST, LOD_RANK_TABLE,"
        " PLACE_LIST]",
        var_type);
  }
}

static void CheckTensorNANOrInf(const std::string& name,
                                const framework::Tensor& tensor) {
  if (tensor.memory_size() == 0) {
    return;
  }
  if (tensor.type().hash_code() != typeid(float).hash_code() &&
      tensor.type().hash_code() != typeid(double).hash_code()) {
    return;
  }
  PADDLE_ENFORCE(!framework::HasInf(tensor), "Tensor %s has Inf", name);
  PADDLE_ENFORCE(!framework::HasNAN(tensor), "Tensor %s has NAN", name);
}

void Executor::Run(const ProgramDesc& pdesc, Scope* scope, int block_id,
                   bool create_local_scope, bool create_vars) {
  // TODO(tonyyang-svail):
  //    - only runs on the first device (i.e. no interdevice communication)
  //    - will change to use multiple blocks for RNN op and Cond Op
  PADDLE_ENFORCE_LT(static_cast<size_t>(block_id), pdesc.Size());
  auto& block = pdesc.Block(block_id);

  Scope* local_scope = scope;
  if (create_vars) {
    if (create_local_scope) {
      local_scope = &scope->NewScope();
      for (auto& var : block.AllVars()) {
        if (var->Name() == framework::kEmptyVarName) {
          continue;
        }

        if (var->Persistable()) {
          auto* ptr = scope->Var(var->Name());
          CreateTensor(ptr, var->GetType());
          VLOG(3) << "Create Variable " << var->Name()
                  << " global, which pointer is " << ptr;
        } else {
          auto* ptr = local_scope->Var(var->Name());
          CreateTensor(ptr, var->GetType());
          VLOG(3) << "Create Variable " << var->Name()
                  << " locally, which pointer is " << ptr;
        }
      }
    } else {
      for (auto& var : block.AllVars()) {
        auto* ptr = local_scope->Var(var->Name());
        CreateTensor(ptr, var->GetType());
        VLOG(3) << "Create variable " << var->Name() << ", which pointer is "
                << ptr;
      }
    }  // if (create_local_scope)
  }    // if (create_vars)

  for (auto& op_desc : block.AllOps()) {
    auto op = paddle::framework::OpRegistry::CreateOp(*op_desc);
    VLOG(4) << op->DebugStringEx(local_scope);

    platform::DeviceContextPool& pool = platform::DeviceContextPool::Instance();
    platform::RecordEvent record_event(op->Type(), pool.Get(place_));

    op->Run(*local_scope, place_);
    VLOG(3) << op->DebugStringEx(local_scope);
    if (FLAGS_do_memory_benchmark) {
      VLOG(2) << "Memory used after operator " + op->Type() + " running: "
              << memory::memory_usage(place_);
    }
    if (FLAGS_check_nan_inf) {
      for (auto& vname : op->OutputVars(true)) {
        auto* var = local_scope->FindVar(vname);
        if (var == nullptr) continue;
        if (var->IsType<framework::LoDTensor>()) {
          CheckTensorNANOrInf(vname, var->Get<framework::LoDTensor>());
        }
      }
    }
  }
  if (create_vars && create_local_scope) {
    scope->DeleteScope(local_scope);
  }
  if (FLAGS_do_memory_benchmark) {
    VLOG(2) << "-------------------------------------------------------";
    VLOG(2) << "Memory used after deleting local scope: "
            << memory::memory_usage(place_);
    VLOG(2) << "-------------------------------------------------------";
  }
}

// Check whether the block already has feed operators and feed_holder.
// Return false if the block does not have any feed operators.
// If some feed operators have been prepended to the block, check that
// the info contained in these feed operators matches the feed_targets
// and feed_holder_name. Raise exception when any mismatch is found.
// Return true if the block has feed operators and holder of matching info.
static bool has_feed_operators(
    BlockDesc* block, std::map<std::string, const LoDTensor*>& feed_targets,
    const std::string& feed_holder_name) {
  size_t feed_count = 0;
  for (auto* op : block->AllOps()) {
    if (op->Type() == kFeedOpType) {
      feed_count++;
      PADDLE_ENFORCE_EQ(op->Input("X")[0], feed_holder_name,
                        "Input to feed op should be '%s'", feed_holder_name);
      std::string feed_target_name = op->Output("Out")[0];
      PADDLE_ENFORCE(
          feed_targets.find(feed_target_name) != feed_targets.end(),
          "Feed operator output name '%s' cannot be found in 'feed_targets'",
          feed_target_name);
    } else {
      break;
    }
  }

  if (feed_count > 0) {
    PADDLE_ENFORCE_EQ(
        feed_count, feed_targets.size(),
        "The number of feed operators should match 'feed_targets'");

    // When feed operator are present, so should be feed_holder
    auto var = block->FindVar(feed_holder_name);
    PADDLE_ENFORCE_NOT_NULL(var, "Block should already have a '%s' variable",
                            feed_holder_name);
    PADDLE_ENFORCE_EQ(var->GetType(), proto::VarDesc::FEED_MINIBATCH,
                      "'%s' variable should be 'FEED_MINIBATCH' type",
                      feed_holder_name);
  }

  return feed_count > 0;
}

// Check whether the block already has fetch operators and fetch_holder.
// Return false if the block does not have any fetch operators.
// If some fetch operators have been appended to the block, check that
// the info contained in these fetch operators matches the fetch_targets
// and fetch_holder_name. Raise exception when any mismatch is found.
// Return true if the block has fetch operators and holder of matching info.
static bool has_fetch_operators(
    BlockDesc* block, std::map<std::string, LoDTensor*>& fetch_targets,
    const std::string& fetch_holder_name) {
  size_t fetch_count = 0;
  for (auto* op : block->AllOps()) {
    if (op->Type() == kFetchOpType) {
      fetch_count++;
      PADDLE_ENFORCE_EQ(op->Output("Out")[0], fetch_holder_name,
                        "Output of fetch op should be '%s'", fetch_holder_name);
      std::string fetch_target_name = op->Input("X")[0];
      PADDLE_ENFORCE(
          fetch_targets.find(fetch_target_name) != fetch_targets.end(),
          "Fetch operator input name '%s' cannot be found in 'fetch_targets'",
          fetch_target_name);
    }
  }

  if (fetch_count > 0) {
    PADDLE_ENFORCE_EQ(
        fetch_count, fetch_targets.size(),
        "The number of fetch operators should match 'fetch_targets'");

    // When fetch operator are present, so should be fetch_holder
    auto var = block->FindVar(fetch_holder_name);
    PADDLE_ENFORCE_NOT_NULL(var, "Block should already have a '%s' variable",
                            fetch_holder_name);
    PADDLE_ENFORCE_EQ(var->GetType(), proto::VarDesc::FETCH_LIST,
                      "'%s' variable should be 'FETCH_LIST' type",
                      fetch_holder_name);
  }

  return fetch_count > 0;
}

void Executor::Run(const ProgramDesc& program, Scope* scope,
                   std::map<std::string, const LoDTensor*>& feed_targets,
                   std::map<std::string, LoDTensor*>& fetch_targets,
                   const std::string& feed_holder_name,
                   const std::string& fetch_holder_name) {
  auto* copy_program = new ProgramDesc(program);
  auto* global_block = copy_program->MutableBlock(0);

  if (!has_feed_operators(global_block, feed_targets, feed_holder_name)) {
    // create feed_holder variable
    auto* feed_holder = global_block->Var(feed_holder_name);
    feed_holder->SetType(proto::VarDesc::FEED_MINIBATCH);
    feed_holder->SetPersistable(true);

    int i = 0;
    for (auto& feed_target : feed_targets) {
      std::string var_name = feed_target.first;
      VLOG(3) << "feed target's name: " << var_name;

      // prepend feed op
      auto* op = global_block->PrependOp();
      op->SetType(kFeedOpType);
      op->SetInput("X", {feed_holder_name});
      op->SetOutput("Out", {var_name});
      op->SetAttr("col", {static_cast<int>(i)});
      op->CheckAttrs();

      i++;
    }
  }

  // map the data of feed_targets to feed_holder
  for (auto* op : global_block->AllOps()) {
    if (op->Type() == kFeedOpType) {
      std::string feed_target_name = op->Output("Out")[0];
      int idx = boost::get<int>(op->GetAttr("col"));
      SetFeedVariable(scope, *feed_targets[feed_target_name], feed_holder_name,
                      idx);
    } else {
      break;
    }
  }

  if (!has_fetch_operators(global_block, fetch_targets, fetch_holder_name)) {
    // create fetch_holder variable
    auto* fetch_holder = global_block->Var(fetch_holder_name);
    fetch_holder->SetType(proto::VarDesc::FETCH_LIST);
    fetch_holder->SetPersistable(true);

    int i = 0;
    for (auto& fetch_target : fetch_targets) {
      std::string var_name = fetch_target.first;
      VLOG(3) << "fetch target's name: " << var_name;

      // append fetch op
      auto* op = global_block->AppendOp();
      op->SetType(kFetchOpType);
      op->SetInput("X", {var_name});
      op->SetOutput("Out", {fetch_holder_name});
      op->SetAttr("col", {static_cast<int>(i)});
      op->CheckAttrs();

      i++;
    }
  }

  Run(*copy_program, scope, 0, true, true);

  // obtain the data of fetch_targets from fetch_holder
  for (auto* op : global_block->AllOps()) {
    if (op->Type() == kFetchOpType) {
      std::string fetch_target_name = op->Input("X")[0];
      int idx = boost::get<int>(op->GetAttr("col"));
      *fetch_targets[fetch_target_name] =
          GetFetchVariable(*scope, fetch_holder_name, idx);
    }
  }

  delete copy_program;
}

}  // namespace framework
}  // namespace paddle
<commit_msg>address comments (#7900)<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

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 "paddle/framework/executor.h"

#include <set>

#include "gflags/gflags.h"
#include "paddle/framework/feed_fetch_method.h"
#include "paddle/framework/feed_fetch_type.h"
#include "paddle/framework/lod_rank_table.h"
#include "paddle/framework/lod_tensor_array.h"
#include "paddle/framework/op_registry.h"
#include "paddle/platform/place.h"
#include "paddle/platform/profiler.h"

DECLARE_bool(do_memory_benchmark);
DEFINE_bool(check_nan_inf, false,
            "Checking whether operator produce NAN/INF or not. It will be "
            "extremely slow so please use this flag wisely.");

namespace paddle {
namespace framework {

const std::string kFeedOpType = "feed";
const std::string kFetchOpType = "fetch";

Executor::Executor(const platform::Place& place) : place_(place) {}

static void CreateTensor(Variable* var, proto::VarDesc::VarType var_type) {
  if (var_type == proto::VarDesc::LOD_TENSOR) {
    var->GetMutable<LoDTensor>();
  } else if (var_type == proto::VarDesc::SELECTED_ROWS) {
    var->GetMutable<SelectedRows>();
  } else if (var_type == proto::VarDesc::FEED_MINIBATCH) {
    var->GetMutable<FeedFetchList>();
  } else if (var_type == proto::VarDesc::FETCH_LIST) {
    var->GetMutable<FeedFetchList>();
  } else if (var_type == proto::VarDesc::STEP_SCOPES) {
    var->GetMutable<std::vector<framework::Scope>>();
  } else if (var_type == proto::VarDesc::LOD_RANK_TABLE) {
    var->GetMutable<LoDRankTable>();
  } else if (var_type == proto::VarDesc::LOD_TENSOR_ARRAY) {
    var->GetMutable<LoDTensorArray>();
  } else if (var_type == proto::VarDesc::PLACE_LIST) {
    var->GetMutable<platform::PlaceList>();
  } else {
    PADDLE_THROW(
        "Variable type %d is not in "
        "[LoDTensor, SelectedRows, FEED_MINIBATCH, FETCH_LIST, LOD_RANK_TABLE,"
        " PLACE_LIST]",
        var_type);
  }
}

static void CheckTensorNANOrInf(const std::string& name,
                                const framework::Tensor& tensor) {
  if (tensor.memory_size() == 0) {
    return;
  }
  if (tensor.type().hash_code() != typeid(float).hash_code() &&
      tensor.type().hash_code() != typeid(double).hash_code()) {
    return;
  }
  PADDLE_ENFORCE(!framework::HasInf(tensor), "Tensor %s has Inf", name);
  PADDLE_ENFORCE(!framework::HasNAN(tensor), "Tensor %s has NAN", name);
}

void Executor::Run(const ProgramDesc& pdesc, Scope* scope, int block_id,
                   bool create_local_scope, bool create_vars) {
  // TODO(tonyyang-svail):
  //    - only runs on the first device (i.e. no interdevice communication)
  //    - will change to use multiple blocks for RNN op and Cond Op
  PADDLE_ENFORCE_LT(static_cast<size_t>(block_id), pdesc.Size());
  auto& block = pdesc.Block(block_id);

  Scope* local_scope = scope;
  if (create_vars) {
    if (create_local_scope) {
      local_scope = &scope->NewScope();
      for (auto& var : block.AllVars()) {
        if (var->Name() == framework::kEmptyVarName) {
          continue;
        }

        if (var->Persistable()) {
          auto* ptr = scope->Var(var->Name());
          CreateTensor(ptr, var->GetType());
          VLOG(3) << "Create Variable " << var->Name()
                  << " global, which pointer is " << ptr;
        } else {
          auto* ptr = local_scope->Var(var->Name());
          CreateTensor(ptr, var->GetType());
          VLOG(3) << "Create Variable " << var->Name()
                  << " locally, which pointer is " << ptr;
        }
      }
    } else {
      for (auto& var : block.AllVars()) {
        auto* ptr = local_scope->Var(var->Name());
        CreateTensor(ptr, var->GetType());
        VLOG(3) << "Create variable " << var->Name() << ", which pointer is "
                << ptr;
      }
    }  // if (create_local_scope)
  }    // if (create_vars)

  for (auto& op_desc : block.AllOps()) {
    auto op = paddle::framework::OpRegistry::CreateOp(*op_desc);
    VLOG(4) << op->DebugStringEx(local_scope);

    platform::DeviceContextPool& pool = platform::DeviceContextPool::Instance();
    platform::RecordEvent record_event(op->Type(), pool.Get(place_));

    op->Run(*local_scope, place_);
    VLOG(3) << op->DebugStringEx(local_scope);
    if (FLAGS_do_memory_benchmark) {
      VLOG(2) << "Memory used after operator " + op->Type() + " running: "
              << memory::memory_usage(place_);
    }
    if (FLAGS_check_nan_inf) {
      for (auto& vname : op->OutputVars(true)) {
        auto* var = local_scope->FindVar(vname);
        if (var == nullptr) continue;
        if (var->IsType<framework::LoDTensor>()) {
          CheckTensorNANOrInf(vname, var->Get<framework::LoDTensor>());
        }
      }
    }
  }
  if (create_vars && create_local_scope) {
    scope->DeleteScope(local_scope);
  }
  if (FLAGS_do_memory_benchmark) {
    VLOG(2) << "-------------------------------------------------------";
    VLOG(2) << "Memory used after deleting local scope: "
            << memory::memory_usage(place_);
    VLOG(2) << "-------------------------------------------------------";
  }
}

// Check whether the block already has feed operators and feed_holder.
// Return false if the block does not have any feed operators.
// If some feed operators have been prepended to the block, check that
// the info contained in these feed operators matches the feed_targets
// and feed_holder_name. Raise exception when any mismatch is found.
// Return true if the block has feed operators and holder of matching info.
static bool has_feed_operators(
    BlockDesc* block, std::map<std::string, const LoDTensor*>& feed_targets,
    const std::string& feed_holder_name) {
  size_t feed_count = 0;
  for (auto* op : block->AllOps()) {
    if (op->Type() == kFeedOpType) {
      feed_count++;
      PADDLE_ENFORCE_EQ(op->Input("X")[0], feed_holder_name,
                        "Input to feed op should be '%s'", feed_holder_name);
      std::string feed_target_name = op->Output("Out")[0];
      PADDLE_ENFORCE(
          feed_targets.find(feed_target_name) != feed_targets.end(),
          "Feed operator output name '%s' cannot be found in 'feed_targets'",
          feed_target_name);
    }
  }

  if (feed_count > 0) {
    PADDLE_ENFORCE_EQ(
        feed_count, feed_targets.size(),
        "The number of feed operators should match 'feed_targets'");

    // When feed operator are present, so should be feed_holder
    auto var = block->FindVar(feed_holder_name);
    PADDLE_ENFORCE_NOT_NULL(var, "Block should already have a '%s' variable",
                            feed_holder_name);
    PADDLE_ENFORCE_EQ(var->GetType(), proto::VarDesc::FEED_MINIBATCH,
                      "'%s' variable should be 'FEED_MINIBATCH' type",
                      feed_holder_name);
  }

  return feed_count > 0;
}

// Check whether the block already has fetch operators and fetch_holder.
// Return false if the block does not have any fetch operators.
// If some fetch operators have been appended to the block, check that
// the info contained in these fetch operators matches the fetch_targets
// and fetch_holder_name. Raise exception when any mismatch is found.
// Return true if the block has fetch operators and holder of matching info.
static bool has_fetch_operators(
    BlockDesc* block, std::map<std::string, LoDTensor*>& fetch_targets,
    const std::string& fetch_holder_name) {
  size_t fetch_count = 0;
  for (auto* op : block->AllOps()) {
    if (op->Type() == kFetchOpType) {
      fetch_count++;
      PADDLE_ENFORCE_EQ(op->Output("Out")[0], fetch_holder_name,
                        "Output of fetch op should be '%s'", fetch_holder_name);
      std::string fetch_target_name = op->Input("X")[0];
      PADDLE_ENFORCE(
          fetch_targets.find(fetch_target_name) != fetch_targets.end(),
          "Fetch operator input name '%s' cannot be found in 'fetch_targets'",
          fetch_target_name);
    }
  }

  if (fetch_count > 0) {
    PADDLE_ENFORCE_EQ(
        fetch_count, fetch_targets.size(),
        "The number of fetch operators should match 'fetch_targets'");

    // When fetch operator are present, so should be fetch_holder
    auto var = block->FindVar(fetch_holder_name);
    PADDLE_ENFORCE_NOT_NULL(var, "Block should already have a '%s' variable",
                            fetch_holder_name);
    PADDLE_ENFORCE_EQ(var->GetType(), proto::VarDesc::FETCH_LIST,
                      "'%s' variable should be 'FETCH_LIST' type",
                      fetch_holder_name);
  }

  return fetch_count > 0;
}

void Executor::Run(const ProgramDesc& program, Scope* scope,
                   std::map<std::string, const LoDTensor*>& feed_targets,
                   std::map<std::string, LoDTensor*>& fetch_targets,
                   const std::string& feed_holder_name,
                   const std::string& fetch_holder_name) {
  auto* copy_program = new ProgramDesc(program);
  auto* global_block = copy_program->MutableBlock(0);

  if (!has_feed_operators(global_block, feed_targets, feed_holder_name)) {
    // create feed_holder variable
    auto* feed_holder = global_block->Var(feed_holder_name);
    feed_holder->SetType(proto::VarDesc::FEED_MINIBATCH);
    feed_holder->SetPersistable(true);

    int i = 0;
    for (auto& feed_target : feed_targets) {
      std::string var_name = feed_target.first;
      VLOG(3) << "feed target's name: " << var_name;

      // prepend feed op
      auto* op = global_block->PrependOp();
      op->SetType(kFeedOpType);
      op->SetInput("X", {feed_holder_name});
      op->SetOutput("Out", {var_name});
      op->SetAttr("col", {static_cast<int>(i)});
      op->CheckAttrs();

      i++;
    }
  }

  // map the data of feed_targets to feed_holder
  for (auto* op : global_block->AllOps()) {
    if (op->Type() == kFeedOpType) {
      std::string feed_target_name = op->Output("Out")[0];
      int idx = boost::get<int>(op->GetAttr("col"));
      SetFeedVariable(scope, *feed_targets[feed_target_name], feed_holder_name,
                      idx);
    }
  }

  if (!has_fetch_operators(global_block, fetch_targets, fetch_holder_name)) {
    // create fetch_holder variable
    auto* fetch_holder = global_block->Var(fetch_holder_name);
    fetch_holder->SetType(proto::VarDesc::FETCH_LIST);
    fetch_holder->SetPersistable(true);

    int i = 0;
    for (auto& fetch_target : fetch_targets) {
      std::string var_name = fetch_target.first;
      VLOG(3) << "fetch target's name: " << var_name;

      // append fetch op
      auto* op = global_block->AppendOp();
      op->SetType(kFetchOpType);
      op->SetInput("X", {var_name});
      op->SetOutput("Out", {fetch_holder_name});
      op->SetAttr("col", {static_cast<int>(i)});
      op->CheckAttrs();

      i++;
    }
  }

  Run(*copy_program, scope, 0, true, true);

  // obtain the data of fetch_targets from fetch_holder
  for (auto* op : global_block->AllOps()) {
    if (op->Type() == kFetchOpType) {
      std::string fetch_target_name = op->Input("X")[0];
      int idx = boost::get<int>(op->GetAttr("col"));
      *fetch_targets[fetch_target_name] =
          GetFetchVariable(*scope, fetch_holder_name, idx);
    }
  }

  delete copy_program;
}

}  // namespace framework
}  // namespace paddle
<|endoftext|>