<commit_before>//===-- XCoreAsmPrinter.cpp - XCore LLVM assembly writer ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains a printer that converts from our internal representation
// of machine-dependent LLVM code to the XAS-format XCore assembly language.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "asm-printer"
#include "XCore.h"
#include "XCoreInstrInfo.h"
#include "XCoreSubtarget.h"
#include "XCoreMCAsmInfo.h"
#include "XCoreTargetMachine.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cctype>
using namespace llvm;

static cl::opt<unsigned> MaxThreads("xcore-max-threads", cl::Optional,
  cl::desc("Maximum number of threads (for emulation thread-local storage)"),
  cl::Hidden,
  cl::value_desc("number"),
  cl::init(8));

namespace {
  class XCoreAsmPrinter : public AsmPrinter {
    const XCoreSubtarget &Subtarget;
  public:
    explicit XCoreAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
      : AsmPrinter(TM, Streamer), Subtarget(TM.getSubtarget<XCoreSubtarget>()){}

    virtual const char *getPassName() const {
      return "XCore Assembly Printer";
    }

    void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
    void printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O,
                       const std::string &directive = ".jmptable");
    void printInlineJT32(const MachineInstr *MI, int opNum, raw_ostream &O) {
      printInlineJT(MI, opNum, O, ".jmptable32");
    }
    void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
    bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                         unsigned AsmVariant, const char *ExtraCode,
                         raw_ostream &O);

    void emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV);
    virtual void EmitGlobalVariable(const GlobalVariable *GV);

    void emitFunctionStart(MachineFunction &MF);

    void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen'd.
    static const char *getRegisterName(unsigned RegNo);

    bool runOnMachineFunction(MachineFunction &MF);
    void EmitInstruction(const MachineInstr *MI);
    void EmitFunctionBodyEnd();
  };
} // end of anonymous namespace

#include "XCoreGenAsmWriter.inc"

void XCoreAsmPrinter::emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV) {
  assert(((GV->hasExternalLinkage() ||
    GV->hasWeakLinkage()) ||
    GV->hasLinkOnceLinkage()) && "Unexpected linkage");
  if (const ArrayType *ATy = dyn_cast<ArrayType>(
    cast<PointerType>(GV->getType())->getElementType())) {
    OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global);
    // FIXME: MCStreamerize.
    OutStreamer.EmitRawText(StringRef(".globound"));
    OutStreamer.EmitRawText("\t.set\t" + Twine(Sym->getName()));
    OutStreamer.EmitRawText(".globound," + Twine(ATy->getNumElements()));
    if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) {
      // TODO Use COMDAT groups for LinkOnceLinkage
      OutStreamer.EmitRawText(MAI->getWeakDefDirective() +Twine(Sym->getName())+
                              ".globound");
    }
  }
}

void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
  // Check to see if this is a special global used by LLVM, if so, emit it.
  if (!GV->hasInitializer() ||
      EmitSpecialLLVMGlobal(GV))
    return;

  const TargetData *TD = TM.getTargetData();
  OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,TM));

  MCSymbol *GVSym = Mang->getSymbol(GV);
  Constant *C = GV->getInitializer();
  unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType());

  // Mark the start of the global
  OutStreamer.EmitRawText("\t.cc_top " + Twine(GVSym->getName()) + ".data," +
                          GVSym->getName());

  switch (GV->getLinkage()) {
  case GlobalValue::AppendingLinkage:
    llvm_report_error("AppendingLinkage is not supported by this target!");
  case GlobalValue::LinkOnceAnyLinkage:
  case GlobalValue::LinkOnceODRLinkage:
  case GlobalValue::WeakAnyLinkage:
  case GlobalValue::WeakODRLinkage:
  case GlobalValue::ExternalLinkage:
    emitArrayBound(GVSym, GV);
    OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);

    // TODO Use COMDAT groups for LinkOnceLinkage
    if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())
      OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak);
    // FALL THROUGH
  case GlobalValue::InternalLinkage:
  case GlobalValue::PrivateLinkage:
  case GlobalValue::LinkerPrivateLinkage:
    break;
  case GlobalValue::DLLImportLinkage:
    llvm_unreachable("DLLImport linkage is not supported by this target!");
  case GlobalValue::DLLExportLinkage:
    llvm_unreachable("DLLExport linkage is not supported by this target!");
  default:
    llvm_unreachable("Unknown linkage type!");
  }

  EmitAlignment(Align, GV, 2);

  unsigned Size = TD->getTypeAllocSize(C->getType());
  if (GV->isThreadLocal()) {
    Size *= MaxThreads;
  }
  if (MAI->hasDotTypeDotSizeDirective()) {
    OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject);
    OutStreamer.EmitRawText("\t.size " + Twine(GVSym->getName()) + "," +
                            Twine(Size));
  }
  OutStreamer.EmitLabel(GVSym);

  EmitGlobalConstant(C);
  if (GV->isThreadLocal()) {
    for (unsigned i = 1; i < MaxThreads; ++i)
      EmitGlobalConstant(C);
  }
  // The ABI requires that unsigned scalar types smaller than 32 bits
  // are padded to 32 bits.
  if (Size < 4)
    OutStreamer.EmitZeros(4 - Size, 0);

  // Mark the end of the global
  OutStreamer.EmitRawText("\t.cc_bottom " + Twine(GVSym->getName()) + ".data");
}

/// Emit the directives on the start of functions
void XCoreAsmPrinter::emitFunctionStart(MachineFunction &MF) {
  // Print out the label for the function.
  const Function *F = MF.getFunction();

  OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));

  // Mark the start of the function
  OutStreamer.EmitRawText("\t.cc_top " + Twine(CurrentFnSym->getName()) +
                          ".function," + CurrentFnSym->getName());

  switch (F->getLinkage()) {
  default: llvm_unreachable("Unknown linkage type!");
  case Function::InternalLinkage:  // Symbols default to internal.
  case Function::PrivateLinkage:
  case Function::LinkerPrivateLinkage:
    break;
  case Function::ExternalLinkage:
    OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_Global);
    break;
  case Function::LinkOnceAnyLinkage:
  case Function::LinkOnceODRLinkage:
  case Function::WeakAnyLinkage:
  case Function::WeakODRLinkage:
    // TODO Use COMDAT groups for LinkOnceLinkage
    OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_Global);
    OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_Weak);
    break;
  }
  // (1 << 1) byte aligned
  EmitAlignment(MF.getAlignment(), F, 1);
  if (MAI->hasDotTypeDotSizeDirective())
    OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction);

  OutStreamer.EmitLabel(CurrentFnSym);
}

/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
/// the last basic block in the function.
void XCoreAsmPrinter::EmitFunctionBodyEnd() {
  // Emit function end directives
  OutStreamer.EmitRawText("\t.cc_bottom " + Twine(CurrentFnSym->getName()) +
                          ".function");
}

/// runOnMachineFunction - This uses the printMachineInstruction()
/// method to print assembly for each instruction.
///
bool XCoreAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
  SetupMachineFunction(MF);

  // Print out constants referenced by the function
  EmitConstantPool();

  // Emit the function start directives
  emitFunctionStart(MF);

  // Emit pre-function debug information.
  DW->BeginFunction(&MF);

  EmitFunctionBody();
  return false;
}

void XCoreAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
                                      raw_ostream &O) {
  printOperand(MI, opNum, O);

  if (MI->getOperand(opNum+1).isImm()
    && MI->getOperand(opNum+1).getImm() == 0)
    return;

  O << "+";
  printOperand(MI, opNum+1, O);
}

void XCoreAsmPrinter::
printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O,
              const std::string &directive) {
  unsigned JTI = MI->getOperand(opNum).getIndex();
  const MachineFunction *MF = MI->getParent()->getParent();
  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
  O << "\t" << directive << " ";
  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
    MachineBasicBlock *MBB = JTBBs[i];
    if (i > 0)
      O << ",";
    O << *MBB->getSymbol();
  }
}

void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
                                   raw_ostream &O) {
  const MachineOperand &MO = MI->getOperand(opNum);
  switch (MO.getType()) {
  case MachineOperand::MO_Register:
    O << getRegisterName(MO.getReg());
    break;
  case MachineOperand::MO_Immediate:
    O << MO.getImm();
    break;
  case MachineOperand::MO_MachineBasicBlock:
    O << *MO.getMBB()->getSymbol();
    break;
  case MachineOperand::MO_GlobalAddress:
    O << *Mang->getSymbol(MO.getGlobal());
    break;
  case MachineOperand::MO_ExternalSymbol:
    O << MO.getSymbolName();
    break;
  case MachineOperand::MO_ConstantPoolIndex:
    O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
      << '_' << MO.getIndex();
    break;
  case MachineOperand::MO_JumpTableIndex:
    O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
      << '_' << MO.getIndex();
    break;
  case MachineOperand::MO_BlockAddress:
    O << *GetBlockAddressSymbol(MO.getBlockAddress());
    break;
  default:
    llvm_unreachable("not implemented");
  }
}

/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                                      unsigned AsmVariant,const char *ExtraCode,
                                      raw_ostream &O) {
  printOperand(MI, OpNo, O);
  return false;
}

void XCoreAsmPrinter::EmitInstruction(const MachineInstr *MI) {
  SmallString<128> Str;
  raw_svector_ostream O(Str);

  // Check for mov mnemonic
  unsigned src, dst, srcSR, dstSR;
  if (TM.getInstrInfo()->isMoveInstr(*MI, src, dst, srcSR, dstSR)) {
    O << "\tmov " << getRegisterName(dst) << ", ";
    O << getRegisterName(src);
  } else {
    printInstruction(MI, O);
  }
  OutStreamer.EmitRawText(O.str());
}

// Force static initialization.
extern "C" void LLVMInitializeXCoreAsmPrinter() {
  RegisterAsmPrinter<XCoreAsmPrinter> X(TheXCoreTarget);
}
<commit_msg>implement EmitFunctionEntryLabel to emit the .cc_top directive, allowing xcore to use the normal runOnMachineFunction  implementation.<commit_after>//===-- XCoreAsmPrinter.cpp - XCore LLVM assembly writer ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains a printer that converts from our internal representation
// of machine-dependent LLVM code to the XAS-format XCore assembly language.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "asm-printer"
#include "XCore.h"
#include "XCoreInstrInfo.h"
#include "XCoreSubtarget.h"
#include "XCoreMCAsmInfo.h"
#include "XCoreTargetMachine.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cctype>
using namespace llvm;

static cl::opt<unsigned> MaxThreads("xcore-max-threads", cl::Optional,
  cl::desc("Maximum number of threads (for emulation thread-local storage)"),
  cl::Hidden,
  cl::value_desc("number"),
  cl::init(8));

namespace {
  class XCoreAsmPrinter : public AsmPrinter {
    const XCoreSubtarget &Subtarget;
  public:
    explicit XCoreAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
      : AsmPrinter(TM, Streamer), Subtarget(TM.getSubtarget<XCoreSubtarget>()){}

    virtual const char *getPassName() const {
      return "XCore Assembly Printer";
    }

    void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
    void printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O,
                       const std::string &directive = ".jmptable");
    void printInlineJT32(const MachineInstr *MI, int opNum, raw_ostream &O) {
      printInlineJT(MI, opNum, O, ".jmptable32");
    }
    void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
    bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                         unsigned AsmVariant, const char *ExtraCode,
                         raw_ostream &O);

    void emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV);
    virtual void EmitGlobalVariable(const GlobalVariable *GV);

    void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen'd.
    static const char *getRegisterName(unsigned RegNo);

    void EmitFunctionEntryLabel();
    void EmitInstruction(const MachineInstr *MI);
    void EmitFunctionBodyEnd();
  };
} // end of anonymous namespace

#include "XCoreGenAsmWriter.inc"

void XCoreAsmPrinter::emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV) {
  assert(((GV->hasExternalLinkage() ||
    GV->hasWeakLinkage()) ||
    GV->hasLinkOnceLinkage()) && "Unexpected linkage");
  if (const ArrayType *ATy = dyn_cast<ArrayType>(
    cast<PointerType>(GV->getType())->getElementType())) {
    OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global);
    // FIXME: MCStreamerize.
    OutStreamer.EmitRawText(StringRef(".globound"));
    OutStreamer.EmitRawText("\t.set\t" + Twine(Sym->getName()));
    OutStreamer.EmitRawText(".globound," + Twine(ATy->getNumElements()));
    if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) {
      // TODO Use COMDAT groups for LinkOnceLinkage
      OutStreamer.EmitRawText(MAI->getWeakDefDirective() +Twine(Sym->getName())+
                              ".globound");
    }
  }
}

void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
  // Check to see if this is a special global used by LLVM, if so, emit it.
  if (!GV->hasInitializer() ||
      EmitSpecialLLVMGlobal(GV))
    return;

  const TargetData *TD = TM.getTargetData();
  OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,TM));

  MCSymbol *GVSym = Mang->getSymbol(GV);
  Constant *C = GV->getInitializer();
  unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType());

  // Mark the start of the global
  OutStreamer.EmitRawText("\t.cc_top " + Twine(GVSym->getName()) + ".data," +
                          GVSym->getName());

  switch (GV->getLinkage()) {
  case GlobalValue::AppendingLinkage:
    llvm_report_error("AppendingLinkage is not supported by this target!");
  case GlobalValue::LinkOnceAnyLinkage:
  case GlobalValue::LinkOnceODRLinkage:
  case GlobalValue::WeakAnyLinkage:
  case GlobalValue::WeakODRLinkage:
  case GlobalValue::ExternalLinkage:
    emitArrayBound(GVSym, GV);
    OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);

    // TODO Use COMDAT groups for LinkOnceLinkage
    if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())
      OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak);
    // FALL THROUGH
  case GlobalValue::InternalLinkage:
  case GlobalValue::PrivateLinkage:
  case GlobalValue::LinkerPrivateLinkage:
    break;
  case GlobalValue::DLLImportLinkage:
    llvm_unreachable("DLLImport linkage is not supported by this target!");
  case GlobalValue::DLLExportLinkage:
    llvm_unreachable("DLLExport linkage is not supported by this target!");
  default:
    llvm_unreachable("Unknown linkage type!");
  }

  EmitAlignment(Align, GV, 2);

  unsigned Size = TD->getTypeAllocSize(C->getType());
  if (GV->isThreadLocal()) {
    Size *= MaxThreads;
  }
  if (MAI->hasDotTypeDotSizeDirective()) {
    OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject);
    OutStreamer.EmitRawText("\t.size " + Twine(GVSym->getName()) + "," +
                            Twine(Size));
  }
  OutStreamer.EmitLabel(GVSym);

  EmitGlobalConstant(C);
  if (GV->isThreadLocal()) {
    for (unsigned i = 1; i < MaxThreads; ++i)
      EmitGlobalConstant(C);
  }
  // The ABI requires that unsigned scalar types smaller than 32 bits
  // are padded to 32 bits.
  if (Size < 4)
    OutStreamer.EmitZeros(4 - Size, 0);

  // Mark the end of the global
  OutStreamer.EmitRawText("\t.cc_bottom " + Twine(GVSym->getName()) + ".data");
}

/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
/// the last basic block in the function.
void XCoreAsmPrinter::EmitFunctionBodyEnd() {
  // Emit function end directives
  OutStreamer.EmitRawText("\t.cc_bottom " + Twine(CurrentFnSym->getName()) +
                          ".function");
}

void XCoreAsmPrinter::EmitFunctionEntryLabel() {
  // Mark the start of the function
  OutStreamer.EmitRawText("\t.cc_top " + Twine(CurrentFnSym->getName()) +
                          ".function," + CurrentFnSym->getName());
  OutStreamer.EmitLabel(CurrentFnSym);
}

void XCoreAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
                                      raw_ostream &O) {
  printOperand(MI, opNum, O);

  if (MI->getOperand(opNum+1).isImm() && MI->getOperand(opNum+1).getImm() == 0)
    return;

  O << "+";
  printOperand(MI, opNum+1, O);
}

void XCoreAsmPrinter::
printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O,
              const std::string &directive) {
  unsigned JTI = MI->getOperand(opNum).getIndex();
  const MachineFunction *MF = MI->getParent()->getParent();
  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
  O << "\t" << directive << " ";
  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
    MachineBasicBlock *MBB = JTBBs[i];
    if (i > 0)
      O << ",";
    O << *MBB->getSymbol();
  }
}

void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
                                   raw_ostream &O) {
  const MachineOperand &MO = MI->getOperand(opNum);
  switch (MO.getType()) {
  case MachineOperand::MO_Register:
    O << getRegisterName(MO.getReg());
    break;
  case MachineOperand::MO_Immediate:
    O << MO.getImm();
    break;
  case MachineOperand::MO_MachineBasicBlock:
    O << *MO.getMBB()->getSymbol();
    break;
  case MachineOperand::MO_GlobalAddress:
    O << *Mang->getSymbol(MO.getGlobal());
    break;
  case MachineOperand::MO_ExternalSymbol:
    O << MO.getSymbolName();
    break;
  case MachineOperand::MO_ConstantPoolIndex:
    O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
      << '_' << MO.getIndex();
    break;
  case MachineOperand::MO_JumpTableIndex:
    O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
      << '_' << MO.getIndex();
    break;
  case MachineOperand::MO_BlockAddress:
    O << *GetBlockAddressSymbol(MO.getBlockAddress());
    break;
  default:
    llvm_unreachable("not implemented");
  }
}

/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                                      unsigned AsmVariant,const char *ExtraCode,
                                      raw_ostream &O) {
  printOperand(MI, OpNo, O);
  return false;
}

void XCoreAsmPrinter::EmitInstruction(const MachineInstr *MI) {
  SmallString<128> Str;
  raw_svector_ostream O(Str);

  // Check for mov mnemonic
  unsigned src, dst, srcSR, dstSR;
  if (TM.getInstrInfo()->isMoveInstr(*MI, src, dst, srcSR, dstSR)) {
    O << "\tmov " << getRegisterName(dst) << ", ";
    O << getRegisterName(src);
  } else {
    printInstruction(MI, O);
  }
  OutStreamer.EmitRawText(O.str());
}

// Force static initialization.
extern "C" void LLVMInitializeXCoreAsmPrinter() {
  RegisterAsmPrinter<XCoreAsmPrinter> X(TheXCoreTarget);
}
<|endoftext|>


<commit_before>#include <node.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace v8;

#ifdef WIN32
    #pragma comment(lib, "NLPIR.lib")
#else
    #include<pthread.h>
    #define OS_LINUX
#endif
#include "NLPIR.h"

Handle<Value> initICTCLAS(const Arguments& args) {
	HandleScope scope;
	Handle<Value> arg = args[0];
  String::Utf8Value initDir(arg);
  bool initRst = NLPIR_Init(*initDir, UTF8_CODE);
  if(!initRst){
    NLPIR_Exit();
  	ThrowException(Exception::TypeError(String::New("initial failure")));
  }
  return scope.Close(Undefined());
}

Handle<Value> importDictFile(const Arguments& args) {
  HandleScope scope;
  Handle<Value> arg = args[0];
  String::Utf8Value dictFile(arg);
  FILE *fp;
  fp = fopen(*dictFile, "r");
  if(fp == NULL){
    ThrowException(Exception::TypeError(String::New("can not open the dict file")));
    return scope.Close(False());
  }
  unsigned wordCount = 0;//ICTCLAS_ImportUserDictFile(*dictFile, CODE_TYPE_UTF8);
  return scope.Close(Number::New(wordCount));
}

Handle<Value> segment(const Arguments& args) {
  HandleScope scope;
  Handle<Value> arg0 = args[0];
  String::Utf8Value txt(arg0);
  const char* sRst = ICTCLAS_ParagraphProcess(*txt);
  return scope.Close(String::New(sRst));
}

Handle<Value> segmentA(const Arguments& args) {
  HandleScope scope;
  Handle<Value> arg0 = args[0];
  String::Utf8Value txt(arg0);
  const char* sRst = ICTCLAS_ParagraphProcess(*txt);
  return scope.Close(String::New(sRst));
}
void Init(Handle<Object> target) {
  NODE_SET_METHOD(target, "init", initICTCLAS);
  NODE_SET_METHOD(target, "segment", segment);
  NODE_SET_METHOD(target, "segmentA", segmentA);
  NODE_SET_METHOD(target, "importDictFile", importDictFile);
}

NODE_MODULE(ictclas, Init)<commit_msg>rm cxx compile waring<commit_after>#include <node.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace v8;

#ifdef WIN32
    #pragma comment(lib, "NLPIR.lib")
#else
    #include<pthread.h>
    #define OS_LINUX
#endif
#include "NLPIR.h"

Handle<Value> initICTCLAS(const Arguments& args) {
	HandleScope scope;
	Handle<Value> arg = args[0];
  String::Utf8Value initDir(arg);
  int initRst = NLPIR_Init(*initDir, UTF8_CODE);
  if(!initRst){
    NLPIR_Exit();
  	ThrowException(Exception::TypeError(String::New("initial failure")));
  }
  return scope.Close(Undefined());
}

Handle<Value> importDictFile(const Arguments& args) {
  HandleScope scope;
  Handle<Value> arg = args[0];
  String::Utf8Value dictFile(arg);
  FILE *fp;
  fp = fopen(*dictFile, "r");
  if(fp == NULL){
    ThrowException(Exception::TypeError(String::New("can not open the dict file")));
    return scope.Close(False());
  }
  unsigned wordCount = 0;//ICTCLAS_ImportUserDictFile(*dictFile, CODE_TYPE_UTF8);
  return scope.Close(Number::New(wordCount));
}

Handle<Value> segment(const Arguments& args) {
  HandleScope scope;
  Handle<Value> arg0 = args[0];
  String::Utf8Value txt(arg0);
  const char* sRst = ICTCLAS_ParagraphProcess(*txt);
  return scope.Close(String::New(sRst));
}

Handle<Value> segmentA(const Arguments& args) {
  HandleScope scope;
  Handle<Value> arg0 = args[0];
  String::Utf8Value txt(arg0);
  const char* sRst = ICTCLAS_ParagraphProcess(*txt);
  return scope.Close(String::New(sRst));
}
void Init(Handle<Object> target) {
  NODE_SET_METHOD(target, "init", initICTCLAS);
  NODE_SET_METHOD(target, "segment", segment);
  NODE_SET_METHOD(target, "segmentA", segmentA);
  NODE_SET_METHOD(target, "importDictFile", importDictFile);
}

NODE_MODULE(ictclas, Init)<|endoftext|>


<commit_before>#include <set>
#include <map>
#include <ruby.h>
#ifdef RUBY_IS_19
#include <ruby/intern.h>
#else
#include <intern.h>
#endif

using std::set;
using std::map;

static VALUE cWeakRef;
static VALUE cRefError;

/* Weakref internal structure. +obj+ is Qnil before initialization and Qundef
 * after finalization */
struct WeakRef {
    VALUE ruby_ref;
    VALUE obj;
};

// Map from real objects to the set of associated WeakRef objects
typedef set<VALUE> ObjSet;
typedef map< VALUE, ObjSet > RefFromObjID;
typedef map< VALUE, VALUE > ObjFromRefID;
RefFromObjID from_obj_id;
ObjFromRefID from_ref_id;

static void weakref_free(WeakRef const* ref)
{
    VALUE ref_id = rb_obj_id(ref->ruby_ref);
    ObjFromRefID::iterator obj_it = from_ref_id.find(ref_id);
    if (obj_it != from_ref_id.end())
    {
        VALUE obj_id = rb_obj_id(obj_it->second);
        RefFromObjID::iterator ref_set = from_obj_id.find(obj_id);
        ref_set->second.erase(ref->ruby_ref);
        from_ref_id.erase(obj_it);
    }
    delete ref;
}
static VALUE weakref_alloc(VALUE klass)
{
    WeakRef* ref = new WeakRef;
    ref->obj = Qnil;
    ref->ruby_ref = Data_Wrap_Struct(klass, NULL, weakref_free, ref);
    return ref->ruby_ref;
}

static WeakRef& get_weakref(VALUE self)
{
    WeakRef* object = 0;
    Data_Get_Struct(self, WeakRef, object);
    return *object;
}

static VALUE do_object_finalize(VALUE mod, VALUE obj_id)
{
    RefFromObjID::iterator ref_set = from_obj_id.find(obj_id);
    if (ref_set != from_obj_id.end())
    {
        ObjSet::iterator it = ref_set->second.begin();
        ObjSet::iterator const end = ref_set->second.end();
        for (; it != end; ++it)
        {
            // Do NOT use Data_Wrap_Struct here, it would break on recent Ruby
            // interpreters. The reason is that the object type is reset during
            // GC -- and the call to free functions is deferred.
            //
            // So, at this point, we're sure we have a RDATA in *it (otherwise
            // weakref_free would have been called), but we can't use
            // Data_Wrap_Struct because that would crash.
            WeakRef& ref = *reinterpret_cast<WeakRef*>(RDATA(*it)->data);;
            ref.obj = Qundef;
            from_ref_id.erase(rb_obj_id(*it));
        }
        from_obj_id.erase(obj_id);
    }
    return Qnil;
}

// Note: the Ruby code has already registered +do_object_finalize+ as the
// finalizer for +obj+.
//
// It is forbidden to make a weakref-of-weakref or a weakref of an immediate
// object
static VALUE weakref_do_initialize(VALUE self, VALUE obj)
{
    if (!FL_ABLE(obj))
    {
        VALUE str = rb_any_to_s(obj);
        rb_raise(rb_eArgError, "%s cannot be finalized", StringValuePtr(str));
    }

    WeakRef& ref = get_weakref(self);
    ref.obj = obj;

    RefFromObjID::iterator it = from_obj_id.find(rb_obj_id(obj));
    if (it == from_obj_id.end())
        it = from_obj_id.insert( make_pair(rb_obj_id(obj), ObjSet()) ).first;

    it->second.insert(self);
    from_ref_id.insert( std::make_pair(rb_obj_id(self), obj) );

    return Qnil;
}

static VALUE weakref_get(VALUE self)
{
    WeakRef const& ref = get_weakref(self);

    if (ref.obj == Qnil)
        rb_raise(cRefError, "initialized weakref");
    if (ref.obj == Qundef)
        rb_raise(cRefError, "finalized object");
    return ref.obj;
}

static VALUE refcount(VALUE mod, VALUE obj)
{
    if (0 == obj & FIXNUM_FLAG)
        obj = rb_obj_id(obj);

    RefFromObjID::const_iterator it = from_obj_id.find(obj);
    if (it == from_obj_id.end())
        return Qnil;
    else
        return INT2FIX(it->second.size());
}

extern "C" void Init_weakref(VALUE mUtilrb)
{
    cWeakRef = rb_define_class_under(mUtilrb, "WeakRef", rb_cObject);
    cRefError = rb_define_class_under(cWeakRef, "RefError", rb_eStandardError);
    rb_define_alloc_func(cWeakRef, weakref_alloc);

    rb_define_singleton_method(cWeakRef, "do_object_finalize", RUBY_METHOD_FUNC(do_object_finalize), 1);
    rb_define_singleton_method(cWeakRef, "refcount", RUBY_METHOD_FUNC(refcount), 1);
    rb_define_method(cWeakRef, "do_initialize", RUBY_METHOD_FUNC(weakref_do_initialize), 1);
    rb_define_method(cWeakRef, "get", RUBY_METHOD_FUNC(weakref_get), 0);
}

<commit_msg>fix gcc warning<commit_after>#include <set>
#include <map>
#include <ruby.h>
#ifdef RUBY_IS_19
#include <ruby/intern.h>
#else
#include <intern.h>
#endif

using std::set;
using std::map;

static VALUE cWeakRef;
static VALUE cRefError;

/* Weakref internal structure. +obj+ is Qnil before initialization and Qundef
 * after finalization */
struct WeakRef {
    VALUE ruby_ref;
    VALUE obj;
};

// Map from real objects to the set of associated WeakRef objects
typedef set<VALUE> ObjSet;
typedef map< VALUE, ObjSet > RefFromObjID;
typedef map< VALUE, VALUE > ObjFromRefID;
RefFromObjID from_obj_id;
ObjFromRefID from_ref_id;

static void weakref_free(WeakRef const* ref)
{
    VALUE ref_id = rb_obj_id(ref->ruby_ref);
    ObjFromRefID::iterator obj_it = from_ref_id.find(ref_id);
    if (obj_it != from_ref_id.end())
    {
        VALUE obj_id = rb_obj_id(obj_it->second);
        RefFromObjID::iterator ref_set = from_obj_id.find(obj_id);
        ref_set->second.erase(ref->ruby_ref);
        from_ref_id.erase(obj_it);
    }
    delete ref;
}
static VALUE weakref_alloc(VALUE klass)
{
    WeakRef* ref = new WeakRef;
    ref->obj = Qnil;
    ref->ruby_ref = Data_Wrap_Struct(klass, NULL, weakref_free, ref);
    return ref->ruby_ref;
}

static WeakRef& get_weakref(VALUE self)
{
    WeakRef* object = 0;
    Data_Get_Struct(self, WeakRef, object);
    return *object;
}

static VALUE do_object_finalize(VALUE mod, VALUE obj_id)
{
    RefFromObjID::iterator ref_set = from_obj_id.find(obj_id);
    if (ref_set != from_obj_id.end())
    {
        ObjSet::iterator it = ref_set->second.begin();
        ObjSet::iterator const end = ref_set->second.end();
        for (; it != end; ++it)
        {
            // Do NOT use Data_Wrap_Struct here, it would break on recent Ruby
            // interpreters. The reason is that the object type is reset during
            // GC -- and the call to free functions is deferred.
            //
            // So, at this point, we're sure we have a RDATA in *it (otherwise
            // weakref_free would have been called), but we can't use
            // Data_Wrap_Struct because that would crash.
            WeakRef& ref = *reinterpret_cast<WeakRef*>(RDATA(*it)->data);;
            ref.obj = Qundef;
            from_ref_id.erase(rb_obj_id(*it));
        }
        from_obj_id.erase(obj_id);
    }
    return Qnil;
}

// Note: the Ruby code has already registered +do_object_finalize+ as the
// finalizer for +obj+.
//
// It is forbidden to make a weakref-of-weakref or a weakref of an immediate
// object
static VALUE weakref_do_initialize(VALUE self, VALUE obj)
{
    if (!FL_ABLE(obj))
    {
        VALUE str = rb_any_to_s(obj);
        rb_raise(rb_eArgError, "%s cannot be finalized", StringValuePtr(str));
    }

    WeakRef& ref = get_weakref(self);
    ref.obj = obj;

    RefFromObjID::iterator it = from_obj_id.find(rb_obj_id(obj));
    if (it == from_obj_id.end())
        it = from_obj_id.insert( make_pair(rb_obj_id(obj), ObjSet()) ).first;

    it->second.insert(self);
    from_ref_id.insert( std::make_pair(rb_obj_id(self), obj) );

    return Qnil;
}

static VALUE weakref_get(VALUE self)
{
    WeakRef const& ref = get_weakref(self);

    if (ref.obj == Qnil)
        rb_raise(cRefError, "initialized weakref");
    if (ref.obj == Qundef)
        rb_raise(cRefError, "finalized object");
    return ref.obj;
}

static VALUE refcount(VALUE mod, VALUE obj)
{
    if (0 == (obj & FIXNUM_FLAG))
        obj = rb_obj_id(obj);

    RefFromObjID::const_iterator it = from_obj_id.find(obj);
    if (it == from_obj_id.end())
        return Qnil;
    else
        return INT2FIX(it->second.size());
}

extern "C" void Init_weakref(VALUE mUtilrb)
{
    cWeakRef = rb_define_class_under(mUtilrb, "WeakRef", rb_cObject);
    cRefError = rb_define_class_under(cWeakRef, "RefError", rb_eStandardError);
    rb_define_alloc_func(cWeakRef, weakref_alloc);

    rb_define_singleton_method(cWeakRef, "do_object_finalize", RUBY_METHOD_FUNC(do_object_finalize), 1);
    rb_define_singleton_method(cWeakRef, "refcount", RUBY_METHOD_FUNC(refcount), 1);
    rb_define_method(cWeakRef, "do_initialize", RUBY_METHOD_FUNC(weakref_do_initialize), 1);
    rb_define_method(cWeakRef, "get", RUBY_METHOD_FUNC(weakref_get), 0);
}

<|endoftext|>


<commit_before>/*! \file tensor_exp.cpp
 *  \brief Python bindings for experimental tensor field types
 *
 *  Both AML and Rodymol currently use an ad-hoc implementation of
 *  scalar, vector, and tensor fields based on Array1D. This module
 *  provides a common set of python bindings for these types. Thistensor types
 *  particular implementation is not part of the "official" NumLib
 *  library since Array1D implements operations that are not
 *  strickly defined for such field types (e.g. division of a
 *  vector field by another vector field). Once, proper field types
 *  have been implemented, this module can be dumped.
 */

#include <boost/python.hpp>
#include "../array/wrap_Array1D.h"
#include "numlib/array/Array1D.h"
#include "numlib/tensor/TensorR1.h"
#include "numlib/tensor/TensorR2.h"

#define WRAP_FIELD1D( Val, PyName )                                     \
	class_< Array1D<Val> >( #PyName ) 									\
		.def(init<numlib::Size>())												\
		.def("resize", &Array1D<Val>::resize) 							\
		.def("__len__", &Array1D<Val>::size) 							\
		.def("__getitem__", &ArrayItem<Val>().get,  					\
					return_value_policy<copy_non_const_reference>() )   \
		.def("__setitem__", &ArrayItem<Val>().set) 						\

BOOST_PYTHON_MODULE( _tensor_exp )
{
	using namespace boost::python;

	WRAP_FIELD1D( numlib::Real, ScalarField1D );
	WRAP_FIELD1D( numlib::tensor::TensorR1, VectorField1D );
	WRAP_FIELD1D( numlib::tensor::TensorR2, TensorField1D );
}
<commit_msg>Cleaned up comments<commit_after>/*! \file tensor_exp.cpp
 *  \brief Python bindings for experimental tensor field types
 *
 *  Both AML and Rodymol currently use an ad-hoc implementation of
 *  scalar, vector, and tensor fields based on Array1D. This module
 *  provides a common set of python bindings for these types. This
 *  ad-hoc implementation of tensor field types is not part of the
 *  "official" NumLib library since Array1D implements operations
 *  that are not strickly defined for such field types (e.g. division
 *  of a vector field by another vector field). Once, proper field types
 *  have been implemented, this module can be discarded.
 */

#include <boost/python.hpp>
#include "../array/wrap_Array1D.h"
#include "numlib/array/Array1D.h"
#include "numlib/tensor/TensorR1.h"
#include "numlib/tensor/TensorR2.h"

#define WRAP_FIELD1D( Val, PyName )                                     \
	class_< Array1D<Val> >( #PyName ) 									\
		.def(init<numlib::Size>())												\
		.def("resize", &Array1D<Val>::resize) 							\
		.def("__len__", &Array1D<Val>::size) 							\
		.def("__getitem__", &ArrayItem<Val>().get,  					\
					return_value_policy<copy_non_const_reference>() )   \
		.def("__setitem__", &ArrayItem<Val>().set) 						\

BOOST_PYTHON_MODULE( _tensor_exp )
{
	using namespace boost::python;

	WRAP_FIELD1D( numlib::Real, ScalarField1D );
	WRAP_FIELD1D( numlib::tensor::TensorR1, VectorField1D );
	WRAP_FIELD1D( numlib::tensor::TensorR2, TensorField1D );
}
<|endoftext|>


<commit_before>#include <string>
#include <cstdint>

extern "C" __declspec(dllexport) const char* getName()
{
	// A pretty name for this compression type
	// Generally, the name of the game it was REd from
	return "1bpp raw (uncompressed) binary";
}

extern "C" __declspec(dllexport) const char* getExt()
{
	// A string suitable for use as a file extension
	return "1bpp";
}

extern "C" __declspec(dllexport) uint32_t compressTiles(uint8_t* source, uint32_t numTiles, uint8_t* dest, uint32_t destLen)
{
	uint32_t sourceLen = numTiles * 32;
	if (sourceLen / 4 > destLen)
	{
		return 0;
	}
	else
	{
		for (uint32_t i = 0; i < sourceLen; ++i)
		{
			*dest++ = *source;
            source += 4;
		}
		return sourceLen / 4;
	}
}
<commit_msg>1bpp plugin over-read the input and over-wrote the output, with no ill effects by chance<commit_after>#include <string>
#include <cstdint>

extern "C" __declspec(dllexport) const char* getName()
{
	// A pretty name for this compression type
	// Generally, the name of the game it was REd from
	return "1bpp raw (uncompressed) binary";
}

extern "C" __declspec(dllexport) const char* getExt()
{
	// A string suitable for use as a file extension
	return "1bpp";
}

extern "C" __declspec(dllexport) uint32_t compressTiles(uint8_t* source, uint32_t numTiles, uint8_t* dest, uint32_t destLen)
{
	uint32_t sourceLen = numTiles * 32;
	uint32_t outputSize = sourceLen / 4;
	if (outputSize > destLen)
	{
		return 0;
	}

	for (uint32_t i = 0; i < outputSize; ++i)
	{
		*dest++ = *source++;
		source += 3;
	}
	return outputSize;
}
<|endoftext|>


<commit_before>#include <babylon/babylon_imgui/babylon_logs_window.h>
#include <imgui_utils/imguial_log.h>
#include <babylon/core/logging.h>
#include <imgui_utils/icons_font_awesome_5.h>

namespace BABYLON
{

  auto logDelegate = SA::delegate<void(const LogMessage&)>{
    [](const BABYLON::LogMessage& logMessage) {
      ImGuiAl::Log::Level levelAl = ImGuiAl::Log::kDebug;
      if (logMessage.level() == LogLevels::LEVEL_INFO)
        levelAl = ImGuiAl::Log::kInfo;
      if (logMessage.level() == LogLevels::LEVEL_TRACE)
        levelAl = ImGuiAl::Log::kDebug;
      if (logMessage.level() == LogLevels::LEVEL_WARN)
        levelAl = ImGuiAl::Log::kWarn;
      if (logMessage.level() == LogLevels::LEVEL_ERROR)
        levelAl = ImGuiAl::Log::kError;
      BabylonLogsWindow::instance().Impl()->Message(logMessage.toString().c_str(), levelAl);
    }};

  BabylonLogsWindow::BabylonLogsWindow()
  {
    LoggerInstance().registerLogMessageListener(LogLevels::LEVEL_DEBUG, logDelegate);
    LoggerInstance().registerLogMessageListener(LogLevels::LEVEL_ERROR, logDelegate);
    LoggerInstance().registerLogMessageListener(LogLevels::LEVEL_INFO, logDelegate);
    LoggerInstance().registerLogMessageListener(LogLevels::LEVEL_TRACE, logDelegate);
    LoggerInstance().registerLogMessageListener(LogLevels::LEVEL_WARN, logDelegate);

    _logImpl = std::make_unique<ImGuiAl::Log>();
    // Initialize
    static const char* actions[] =
    {
      ICON_FA_COPY " Copy",
      ICON_FA_RECYCLE " Clear",
      NULL
    };

    _logImpl->Init(ImGuiAl::Log::kShowFilters, actions);
    _logImpl->SetLabel(ImGuiAl::Log::kDebug, ICON_FA_BUG " Debug");
    _logImpl->SetLabel(ImGuiAl::Log::kInfo, ICON_FA_INFO " Info");
    _logImpl->SetLabel(ImGuiAl::Log::kWarn, ICON_FA_EXCLAMATION_TRIANGLE " Warn");
    _logImpl->SetLabel(ImGuiAl::Log::kError, ICON_FA_WRENCH " Error");
    _logImpl->SetCumulativeLabel(" Cumulative");
    _logImpl->SetFilterHeaderLabel(ICON_FA_FILTER " Filters");
    _logImpl->SetFilterLabel(ICON_FA_SEARCH " Filter (inc,-exc)");

  }

  BabylonLogsWindow::~BabylonLogsWindow() = default;

  BABYLON::BabylonLogsWindow& BabylonLogsWindow::instance()
  {
    static BabylonLogsWindow instance;
    return instance;
  }

  void BabylonLogsWindow::render()
  {
    bool popStyle = false;
    if (_visible)
    {
      ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.3f, 0.3f, 0.6f, 1.f));
      popStyle = true;
    }

    if (ImGui::Button(ICON_FA_INFO " Logs"))
      _visible = true;

    if (_visible)
    {
      ImGui::SetNextWindowSize(ImVec2(800, 300), ImGuiCond_Once);
      ImGui::SetNextWindowPos(ImVec2(30, 60), ImGuiCond_Once);
      ImGui::Begin("Logs", &_visible);
      _logImpl->Draw();
      ImGui::End();
    }
    if (popStyle)
      ImGui::PopStyleColor();
  }

  void BabylonLogsWindow::setVisible(bool visible)
  {
    _visible = visible;
  }

  ImGuiAl::Log * BabylonLogsWindow::Impl()
  {
    return _logImpl.get();
  }

}<commit_msg>fixup add babylon_logs_window<commit_after>#include <babylon/babylon_imgui/babylon_logs_window.h>
#include <imgui_utils/imguial_log.h>
#include <babylon/core/logging.h>
#include <imgui_utils/icons_font_awesome_5.h>

namespace BABYLON
{

  auto logDelegate = SA::delegate<void(const LogMessage&)>{
    [](const BABYLON::LogMessage& logMessage) {
      ImGuiAl::Log::Level levelAl = ImGuiAl::Log::kDebug;
      if (logMessage.level() == LogLevels::LEVEL_INFO)
        levelAl = ImGuiAl::Log::kInfo;
      if (logMessage.level() == LogLevels::LEVEL_TRACE)
        levelAl = ImGuiAl::Log::kDebug;
      if (logMessage.level() == LogLevels::LEVEL_WARN)
        levelAl = ImGuiAl::Log::kWarn;
      if (logMessage.level() == LogLevels::LEVEL_ERROR)
        levelAl = ImGuiAl::Log::kError;
      BabylonLogsWindow::instance().Impl()->Message(logMessage.toString().c_str(), levelAl);
    }};

  BabylonLogsWindow::BabylonLogsWindow()
  {
    LoggerInstance().registerLogMessageListener(LogLevels::LEVEL_DEBUG, logDelegate);
    LoggerInstance().registerLogMessageListener(LogLevels::LEVEL_ERROR, logDelegate);
    LoggerInstance().registerLogMessageListener(LogLevels::LEVEL_INFO, logDelegate);
    LoggerInstance().registerLogMessageListener(LogLevels::LEVEL_TRACE, logDelegate);
    LoggerInstance().registerLogMessageListener(LogLevels::LEVEL_WARN, logDelegate);

    _logImpl = std::make_unique<ImGuiAl::Log>();
    // Initialize
    static const char* actions[] =
    {
      ICON_FA_COPY " Copy",
      ICON_FA_RECYCLE " Clear",
      NULL
    };

    _logImpl->Init(ImGuiAl::Log::kShowFilters, actions);
    _logImpl->SetLabel(ImGuiAl::Log::kDebug, ICON_FA_BUG " Debug");
    _logImpl->SetLabel(ImGuiAl::Log::kInfo, ICON_FA_INFO " Info");
    _logImpl->SetLabel(ImGuiAl::Log::kWarn, ICON_FA_EXCLAMATION_TRIANGLE " Warn");
    _logImpl->SetLabel(ImGuiAl::Log::kError, ICON_FA_WRENCH " Error");
    _logImpl->SetCumulativeLabel(" Cumulative");
    _logImpl->SetFilterHeaderLabel(ICON_FA_FILTER " Filters");
    _logImpl->SetFilterLabel(ICON_FA_SEARCH " Filter (inc,-exc)");

  }

  BabylonLogsWindow::~BabylonLogsWindow() = default;

  BABYLON::BabylonLogsWindow& BabylonLogsWindow::instance()
  {
    static BabylonLogsWindow instance;
    return instance;
  }

  void BabylonLogsWindow::render()
  {
    bool popStyle = false;
    if (_visible)
    {
      ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.3f, 0.3f, 0.6f, 1.f));
      popStyle = true;
    }

    if (ImGui::Button(ICON_FA_INFO " Logs"))
      _visible = !_visible;

    if (_visible)
    {
      ImGui::SetNextWindowSize(ImVec2(800, 300), ImGuiCond_FirstUseEver);
      ImGui::SetNextWindowPos(ImVec2(30, 60), ImGuiCond_FirstUseEver);
      ImGui::Begin("Logs", &_visible);
      _logImpl->Draw();
      ImGui::End();
    }
    if (popStyle)
      ImGui::PopStyleColor();
  }

  void BabylonLogsWindow::setVisible(bool visible)
  {
    _visible = visible;
  }

  ImGuiAl::Log * BabylonLogsWindow::Impl()
  {
    return _logImpl.get();
  }

}<|endoftext|>


<commit_before>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "core/CompileConfig.h"

#if OUZEL_PLATFORM_RASPBIAN && OUZEL_SUPPORTS_OPENGL

#include "RendererOGLRasp.h"
#include "core/Engine.h"
#include "core/raspbian/WindowRasp.h"
#include "utils/Log.h"

namespace ouzel
{
    namespace graphics
    {
        RendererOGLRasp::RendererOGLRasp():
            running(false)
        {
        }

        RendererOGLRasp::~RendererOGLRasp()
        {
            running = false;
            if (renderThread.joinable()) renderThread.join();

            if (context)
            {
                if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
                {
                    Log(Log::Level::ERR) << "Failed to unset EGL context";
                }

                if (!eglDestroyContext(display, context))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL context";
                }
            }

            if (surface)
            {
                if (!eglDestroySurface(display, surface))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL surface";
                }
            }

            if (display)
            {
                if (!eglTerminate(display))
                {
                    Log(Log::Level::ERR) << "Failed to terminate EGL";
                }
            }
        }

        bool RendererOGLRasp::init(Window* newWindow,
                                   const Size2& newSize,
                                   uint32_t newSampleCount,
                                   Texture::Filter newTextureFilter,
                                   uint32_t newMaxAnisotropy,
                                   bool newVerticalSync,
                                   bool newDepth,
                                   bool newDebugRenderer)
        {
            display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

            if (!display)
            {
                Log(Log::Level::ERR) << "Failed to get display";
                return false;
            }

            if (!eglInitialize(display, nullptr, nullptr))
            {
                Log(Log::Level::ERR) << "Failed to initialize EGL";
                return false;
            }

            const EGLint attributeList[] =
            {
                EGL_RED_SIZE, 8,
                EGL_GREEN_SIZE, 8,
                EGL_BLUE_SIZE, 8,
                EGL_ALPHA_SIZE, 8,
                EGL_DEPTH_SIZE, newDepth ? 24 : 0,
                EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
                EGL_SAMPLE_BUFFERS, (newSampleCount > 1) ? 1 : 0,
                EGL_SAMPLES, static_cast<int>(newSampleCount),
                EGL_NONE
            };
            EGLConfig config;
            EGLint numConfig;
            if (!eglChooseConfig(display, attributeList, &config, 1, &numConfig))
            {
                Log(Log::Level::ERR) << "Failed to choose EGL config";
                return false;
            }

            if (!eglBindAPI(EGL_OPENGL_ES_API))
            {
                Log(Log::Level::ERR) << "Failed to bind OpenGL ES API";
                return false;
            }

            uint32_t width = static_cast<uint32_t>(newSize.v[0]);
            uint32_t height = static_cast<uint32_t>(newSize.v[1]);

            VC_RECT_T dstRect;
            dstRect.x = 0;
            dstRect.y = 0;
            dstRect.width = width;
            dstRect.height = height;

            VC_RECT_T srcRect;
            srcRect.x = 0;
            srcRect.y = 0;
            srcRect.width = width;
            srcRect.height = height;

            DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = vc_dispmanx_display_open(0);
            DISPMANX_UPDATE_HANDLE_T dispmanUpdate = vc_dispmanx_update_start(0);

            DISPMANX_ELEMENT_HANDLE_T dispmanElement = vc_dispmanx_element_add(dispmanUpdate, dispmanDisplay,
                        0, &dstRect, 0,
                        &srcRect, DISPMANX_PROTECTION_NONE,
                        0, 0, DISPMANX_NO_ROTATE);

            nativewindow.element = dispmanElement;
            nativewindow.width = width;
            nativewindow.height = height;
            vc_dispmanx_update_submit_sync(dispmanUpdate);

            surface = eglCreateWindowSurface(display, config, reinterpret_cast<EGLNativeWindowType>(&nativewindow), nullptr);
            if (surface == EGL_NO_SURFACE)
            {
                Log(Log::Level::ERR) << "Failed to create EGL window surface";
                return false;
            }

            for (EGLint version = 3; version >= 2; --version)
            {
                std::vector<EGLint> contextAttributes =
                {
                    EGL_CONTEXT_CLIENT_VERSION, version
                };

                if (newDebugRenderer)
                {
                    contextAttributes.push_back(EGL_CONTEXT_FLAGS_KHR);
                    contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR);
                }

                contextAttributes.push_back(EGL_NONE);

                context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes.data());

                if (context != EGL_NO_CONTEXT)
                {
                    apiMajorVersion = version;
                    apiMinorVersion = 0;
                    Log(Log::Level::INFO) << "EGL OpenGL ES " << version << " context created";
                    break;
                }
            }

            if (context == EGL_NO_CONTEXT)
            {
                Log(Log::Level::ERR) << "Failed to create EGL context";
                return false;
            }

            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context";
                return false;
            }

            if (!eglSwapInterval(display, newVerticalSync ? 1 : 0))
            {
                Log(Log::Level::ERR) << "Failed to set EGL frame interval";
                return false;
            }

            if (!RendererOGL::init(newWindow,
                                   newSize,
                                   newSampleCount,
                                   newTextureFilter,
                                   newMaxAnisotropy,
                                   newVerticalSync,
                                   newDepth,
                                   newDebugRenderer))
            {
                return false;
            }

            if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
            {
                Log(Log::Level::ERR) << "Failed to unset EGL context";
                return false;
            }

            running = true;
            renderThread = std::thread(&RendererOGLRasp::main, this);

            return true;
        }

        bool RendererOGLRasp::lockContext()
        {
            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context";
                return false;
            }

            return true;
        }

        bool RendererOGLRasp::swapBuffers()
        {
            if (eglSwapBuffers(display, surface) != EGL_TRUE)
            {
                Log(Log::Level::ERR) << "Failed to swap buffers " << eglGetError();
                return false;
            }

            return true;
        }

        void RendererOGLRasp::main()
        {
            while (running)
            {
                process();
            }
        }
    } // namespace graphics
} // namespace ouzel

#endif
<commit_msg>Print EGL error<commit_after>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "core/CompileConfig.h"

#if OUZEL_PLATFORM_RASPBIAN && OUZEL_SUPPORTS_OPENGL

#include "RendererOGLRasp.h"
#include "core/Engine.h"
#include "core/raspbian/WindowRasp.h"
#include "utils/Log.h"

namespace ouzel
{
    namespace graphics
    {
        RendererOGLRasp::RendererOGLRasp():
            running(false)
        {
        }

        RendererOGLRasp::~RendererOGLRasp()
        {
            running = false;
            if (renderThread.joinable()) renderThread.join();

            if (context)
            {
                if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
                {
                    Log(Log::Level::ERR) << "Failed to unset EGL context, error: " << eglGetError();
                }

                if (!eglDestroyContext(display, context))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL context, error: " << eglGetError();
                }
            }

            if (surface)
            {
                if (!eglDestroySurface(display, surface))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL surface, error: " << eglGetError();
                }
            }

            if (display)
            {
                if (!eglTerminate(display))
                {
                    Log(Log::Level::ERR) << "Failed to terminate EGL";
                }
            }
        }

        bool RendererOGLRasp::init(Window* newWindow,
                                   const Size2& newSize,
                                   uint32_t newSampleCount,
                                   Texture::Filter newTextureFilter,
                                   uint32_t newMaxAnisotropy,
                                   bool newVerticalSync,
                                   bool newDepth,
                                   bool newDebugRenderer)
        {
            display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

            if (!display)
            {
                Log(Log::Level::ERR) << "Failed to get display, error: " << eglGetError();
                return false;
            }

            if (!eglInitialize(display, nullptr, nullptr))
            {
                Log(Log::Level::ERR) << "Failed to initialize EGL, error: " << eglGetError();
                return false;
            }

            const EGLint attributeList[] =
            {
                EGL_RED_SIZE, 8,
                EGL_GREEN_SIZE, 8,
                EGL_BLUE_SIZE, 8,
                EGL_ALPHA_SIZE, 8,
                EGL_DEPTH_SIZE, newDepth ? 24 : 0,
                EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
                EGL_SAMPLE_BUFFERS, (newSampleCount > 1) ? 1 : 0,
                EGL_SAMPLES, static_cast<int>(newSampleCount),
                EGL_NONE
            };
            EGLConfig config;
            EGLint numConfig;
            if (!eglChooseConfig(display, attributeList, &config, 1, &numConfig))
            {
                Log(Log::Level::ERR) << "Failed to choose EGL config, error: " << eglGetError();
                return false;
            }

            if (!eglBindAPI(EGL_OPENGL_ES_API))
            {
                Log(Log::Level::ERR) << "Failed to bind OpenGL ES API, error: " << eglGetError();
                return false;
            }

            uint32_t width = static_cast<uint32_t>(newSize.v[0]);
            uint32_t height = static_cast<uint32_t>(newSize.v[1]);

            VC_RECT_T dstRect;
            dstRect.x = 0;
            dstRect.y = 0;
            dstRect.width = width;
            dstRect.height = height;

            VC_RECT_T srcRect;
            srcRect.x = 0;
            srcRect.y = 0;
            srcRect.width = width;
            srcRect.height = height;

            DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = vc_dispmanx_display_open(0);
            DISPMANX_UPDATE_HANDLE_T dispmanUpdate = vc_dispmanx_update_start(0);

            DISPMANX_ELEMENT_HANDLE_T dispmanElement = vc_dispmanx_element_add(dispmanUpdate, dispmanDisplay,
                        0, &dstRect, 0,
                        &srcRect, DISPMANX_PROTECTION_NONE,
                        0, 0, DISPMANX_NO_ROTATE);

            nativewindow.element = dispmanElement;
            nativewindow.width = width;
            nativewindow.height = height;
            vc_dispmanx_update_submit_sync(dispmanUpdate);

            surface = eglCreateWindowSurface(display, config, reinterpret_cast<EGLNativeWindowType>(&nativewindow), nullptr);
            if (surface == EGL_NO_SURFACE)
            {
                Log(Log::Level::ERR) << "Failed to create EGL window surface, error: " << eglGetError();
                return false;
            }

            for (EGLint version = 3; version >= 2; --version)
            {
                std::vector<EGLint> contextAttributes =
                {
                    EGL_CONTEXT_CLIENT_VERSION, version
                };

                if (newDebugRenderer)
                {
                    contextAttributes.push_back(EGL_CONTEXT_FLAGS_KHR);
                    contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR);
                }

                contextAttributes.push_back(EGL_NONE);

                context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes.data());

                if (context != EGL_NO_CONTEXT)
                {
                    apiMajorVersion = version;
                    apiMinorVersion = 0;
                    Log(Log::Level::INFO) << "EGL OpenGL ES " << version << " context created";
                    break;
                }
            }

            if (context == EGL_NO_CONTEXT)
            {
                Log(Log::Level::ERR) << "Failed to create EGL context, error: " << eglGetError();
                return false;
            }

            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context, error: " << eglGetError();
                return false;
            }

            if (!eglSwapInterval(display, newVerticalSync ? 1 : 0))
            {
                Log(Log::Level::ERR) << "Failed to set EGL frame interval, error: " << eglGetError();
                return false;
            }

            if (!RendererOGL::init(newWindow,
                                   newSize,
                                   newSampleCount,
                                   newTextureFilter,
                                   newMaxAnisotropy,
                                   newVerticalSync,
                                   newDepth,
                                   newDebugRenderer))
            {
                return false;
            }

            if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
            {
                Log(Log::Level::ERR) << "Failed to unset EGL context, error: " << eglGetError();
                return false;
            }

            running = true;
            renderThread = std::thread(&RendererOGLRasp::main, this);

            return true;
        }

        bool RendererOGLRasp::lockContext()
        {
            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context, error: " << eglGetError();
                return false;
            }

            return true;
        }

        bool RendererOGLRasp::swapBuffers()
        {
            if (eglSwapBuffers(display, surface) != EGL_TRUE)
            {
                Log(Log::Level::ERR) << "Failed to swap buffers, error: " << eglGetError();
                return false;
            }

            return true;
        }

        void RendererOGLRasp::main()
        {
            while (running)
            {
                process();
            }
        }
    } // namespace graphics
} // namespace ouzel

#endif
<|endoftext|>


<commit_before>
#include "diff_system.h"
#include "libmesh_logging.h"
#include "linear_solver.h"
#include "newton_solver.h"
#include "numeric_vector.h"
#include "sparse_matrix.h"
#include "dof_map.h"

NewtonSolver::NewtonSolver (sys_type& s)
  : Parent(s),
    require_residual_reduction(false),
    minsteplength(0.0),
    linear_solver(LinearSolver<Number>::build())
{
}

NewtonSolver::~NewtonSolver ()
{
}

void NewtonSolver::reinit()
{
  Parent::reinit();

  linear_solver->clear();
}

void NewtonSolver::solve()
{
  START_LOG("solve()", "NewtonSolver");

// Amount by which nonlinear residual should exceed linear solver
// tolerance
const Real relative_tolerance = 1.e-3;

  NumericVector<Number> &solution = *(_system.solution);
  NumericVector<Number> &newton_iterate =
    _system.get_vector("_nonlinear_solution");
  newton_iterate.close();
//  solution.close();

  NumericVector<Number> &rhs = *(_system.rhs);

  SparseMatrix<Number> &matrix = *(_system.matrix);

  // Prepare to take incomplete steps
  Real last_residual=0.;

  // Set starting linear tolerance
  Real current_linear_tolerance = initial_linear_tolerance;

  // Now we begin the nonlinear loop
  for (unsigned int l=0; l<max_nonlinear_iterations; ++l)
    {
      if (!quiet)
        std::cout << "Assembling System" << std::endl;

      PAUSE_LOG("solve()", "NewtonSolver");
      _system.assembly(true, true);
      RESTART_LOG("solve()", "NewtonSolver");
      rhs.close();
      Real current_residual = rhs.l2_norm();
      last_residual = current_residual;

      if (isnan(current_residual))
        {
          std::cout << "  Nonlinear solver DIVERGED at step " << l
                    << " with norm Not-a-Number"
                    << std::endl;
          error();
          continue;
        }

      max_residual_norm = std::max (current_residual,
                                    max_residual_norm);

      // Compute the l2 norm of the whole solution
      Real norm_total = newton_iterate.l2_norm();

      max_solution_norm = std::max(max_solution_norm, norm_total);

      if (!quiet)
        std::cout << "Nonlinear Residual: "
                  << current_residual << std::endl;

      // Make sure our linear tolerance is low enough
      if (current_linear_tolerance > current_residual * relative_tolerance)
        {
          current_linear_tolerance = current_residual * relative_tolerance;
        }

      // But don't let it be zero
      if (current_linear_tolerance == 0.)
        {
          current_linear_tolerance = TOLERANCE * TOLERANCE;
        }

      // At this point newton_iterate is the current guess, and
      // solution is now about to become the NEGATIVE of the next
      // Newton step.

      // Our best initial guess for the solution is zero!
      solution.zero();

      if (!quiet)
        std::cout << "Linear solve starting" << std::endl;

      PAUSE_LOG("solve()", "NewtonSolver");
      // Solve the linear system.  Two cases:
      const std::pair<unsigned int, Real> rval =
        (_system.have_matrix("Preconditioner")) ?
      // 1.) User-supplied preconditioner
        linear_solver->solve (matrix, _system.get_matrix("Preconditioner"),
                              solution, rhs, current_linear_tolerance,
                              max_linear_iterations) :
      // 2.) Use system matrix for the preconditioner
        linear_solver->solve (matrix, solution, rhs,
                              current_linear_tolerance,
                              max_linear_iterations);
      // We may need to localize a parallel solution
      _system.update ();
      RESTART_LOG("solve()", "NewtonSolver");
      // The linear solver may not have fit our constraints exactly
      _system.get_dof_map().enforce_constraints_exactly(_system);

      if (!quiet)
        std::cout << "Linear solve finished, step " << rval.first
                  << ", residual " << rval.second
                  << ", tolerance " << current_linear_tolerance
                  << std::endl;

      // Compute the l2 norm of the nonlinear update
      Real norm_delta = solution.l2_norm();

      if (!quiet)
        std::cout << "Trying full Newton step" << std::endl;
      // Take a full Newton step
      newton_iterate.add (-1., solution);
//      newton_iterate.close();

      // Check residual with full Newton step
      Real steplength = 1.;
      PAUSE_LOG("solve()", "NewtonSolver");
      _system.assembly(true, false);
      RESTART_LOG("solve()", "NewtonSolver");

      rhs.close();
      current_residual = rhs.l2_norm();

      // backtrack if necessary
      if (require_residual_reduction)
        {
          // but don't fiddle around if we've already converged
          if (test_convergence(current_residual, norm_delta))
            {
              if (!quiet)
		print_convergence(l, current_residual, norm_delta);
              break;
            }

          while (current_residual > last_residual)
            {
              // Reduce step size to 1/2, 1/4, etc.
              steplength /= 2.;
              norm_delta /= 2.;
              if (!quiet)
                std::cout << "Shrinking Newton step to "
                          << steplength << std::endl;
              newton_iterate.add (steplength, solution);
//              newton_iterate.close();

              // Check residual with fractional Newton step
              PAUSE_LOG("solve()", "NewtonSolver");
              _system.assembly (true, false);
              RESTART_LOG("solve()", "NewtonSolver");

              rhs.close();
              current_residual = rhs.l2_norm();
              if (!quiet)
                std::cout << "Current Residual: "
                          << current_residual << std::endl;

              if (steplength/2. < minsteplength &&
                  current_residual > last_residual)
                {
                  std::cout << "Inexact Newton step FAILED at step "
                            << l << std::endl;

                  error();
                }
            }
        }

      // Compute the l2 norm of the whole solution
      norm_total = newton_iterate.l2_norm();

      max_solution_norm = std::max(max_solution_norm, norm_total);

      // Print out information for the
      // nonlinear iterations.
      if (!quiet)
        std::cout << "  Nonlinear step: |du|/|u| = "
                  << norm_delta / norm_total
                  << ", |du| = " << norm_delta
                  << std::endl;

      // Terminate the solution iteration if the difference between
      // this iteration and the last is sufficiently small.
      if (!quiet)
        print_convergence(l, current_residual,
                          norm_delta / steplength);
      if (test_convergence(current_residual, norm_delta / steplength))
        {
          break;
        }
      if (l >= max_nonlinear_iterations - 1)
        {
          std::cout << "  Nonlinear solver FAILED TO CONVERGE by step " << l
                    << " with norm " << norm_total
                    << std::endl;
          error();
          continue;
        }
    } // end nonlinear loop

  // Copy the final nonlinear iterate into the current_solution,
  // for other libMesh functions that expect it

  solution = newton_iterate;
//  solution.close();

  // We may need to localize a parallel solution
  _system.update ();

  STOP_LOG("solve()", "NewtonSolver");
}

bool NewtonSolver::test_convergence(Real current_residual,
                                    Real step_norm)
{
  // We haven't converged unless we pass a convergence test
  bool has_converged = false;

  // Is our absolute residual low enough?
  if (current_residual < absolute_residual_tolerance)
    has_converged = true;

  // Is our relative residual low enough?
  if ((current_residual / max_residual_norm) <
      relative_residual_tolerance)
    has_converged = true;

  // Is our absolute Newton step size small enough?
  if (step_norm < absolute_step_tolerance)
    has_converged = true;

  // Is our relative Newton step size small enough?
  if (step_norm / max_solution_norm <
      relative_step_tolerance)
    has_converged = true;

  return has_converged;
}

void NewtonSolver::print_convergence(unsigned int step_num,
                                     Real current_residual,
                                     Real step_norm)
{
  // Is our absolute residual low enough?
  if (current_residual < absolute_residual_tolerance)
    {
      std::cout << "  Nonlinear solver converged, step " << step_num
                << ", residual " << current_residual
                << std::endl;
    }
  else if (absolute_residual_tolerance)
    {
      std::cout << "  Nonlinear solver current_residual "
                << current_residual << " > "
                << (absolute_residual_tolerance) << std::endl;
    }

  // Is our relative residual low enough?
  if ((current_residual / max_residual_norm) <
      relative_residual_tolerance)
    {
      std::cout << "  Nonlinear solver converged, step " << step_num
                << ", residual reduction "
                << current_residual / max_residual_norm
                << " < " << relative_residual_tolerance
                << std::endl;
    }
  else if (relative_residual_tolerance)
    {
      if (!quiet)
        std::cout << "  Nonlinear solver relative residual "
                  << (current_residual / max_residual_norm)
                  << " > " << relative_residual_tolerance
                  << std::endl;
    }

  // Is our absolute Newton step size small enough?
  if (step_norm < absolute_step_tolerance)
    {
      std::cout << "  Nonlinear solver converged, step " << step_num
                << ", absolute step size "
                << step_norm
                << " < " << absolute_step_tolerance
                << std::endl;
    }
  else if (absolute_step_tolerance)
    {
      std::cout << "  Nonlinear solver absolute step size "
                << step_norm
                << " > " << absolute_step_tolerance
                << std::endl;
    }

  // Is our relative Newton step size small enough?
  if (step_norm / max_solution_norm <
      relative_step_tolerance)
    {
      std::cout << "  Nonlinear solver converged, step " << step_num
                << ", relative step size "
                << (step_norm / max_solution_norm)
                << " < " << relative_step_tolerance
                << std::endl;
    }
  else if (relative_step_tolerance)
    {
      std::cout << "  Nonlinear solver relative step size "
                << (step_norm / max_solution_norm)
                << " > " << relative_step_tolerance
                << std::endl;
    }
}
<commit_msg>Need math.h for isnan()<commit_after>
#include "math.h"

#include "diff_system.h"
#include "libmesh_logging.h"
#include "linear_solver.h"
#include "newton_solver.h"
#include "numeric_vector.h"
#include "sparse_matrix.h"
#include "dof_map.h"

NewtonSolver::NewtonSolver (sys_type& s)
  : Parent(s),
    require_residual_reduction(false),
    minsteplength(0.0),
    linear_solver(LinearSolver<Number>::build())
{
}

NewtonSolver::~NewtonSolver ()
{
}

void NewtonSolver::reinit()
{
  Parent::reinit();

  linear_solver->clear();
}

void NewtonSolver::solve()
{
  START_LOG("solve()", "NewtonSolver");

// Amount by which nonlinear residual should exceed linear solver
// tolerance
const Real relative_tolerance = 1.e-3;

  NumericVector<Number> &solution = *(_system.solution);
  NumericVector<Number> &newton_iterate =
    _system.get_vector("_nonlinear_solution");
  newton_iterate.close();
//  solution.close();

  NumericVector<Number> &rhs = *(_system.rhs);

  SparseMatrix<Number> &matrix = *(_system.matrix);

  // Prepare to take incomplete steps
  Real last_residual=0.;

  // Set starting linear tolerance
  Real current_linear_tolerance = initial_linear_tolerance;

  // Now we begin the nonlinear loop
  for (unsigned int l=0; l<max_nonlinear_iterations; ++l)
    {
      if (!quiet)
        std::cout << "Assembling System" << std::endl;

      PAUSE_LOG("solve()", "NewtonSolver");
      _system.assembly(true, true);
      RESTART_LOG("solve()", "NewtonSolver");
      rhs.close();
      Real current_residual = rhs.l2_norm();
      last_residual = current_residual;

      if (isnan(current_residual))
        {
          std::cout << "  Nonlinear solver DIVERGED at step " << l
                    << " with norm Not-a-Number"
                    << std::endl;
          error();
          continue;
        }

      max_residual_norm = std::max (current_residual,
                                    max_residual_norm);

      // Compute the l2 norm of the whole solution
      Real norm_total = newton_iterate.l2_norm();

      max_solution_norm = std::max(max_solution_norm, norm_total);

      if (!quiet)
        std::cout << "Nonlinear Residual: "
                  << current_residual << std::endl;

      // Make sure our linear tolerance is low enough
      if (current_linear_tolerance > current_residual * relative_tolerance)
        {
          current_linear_tolerance = current_residual * relative_tolerance;
        }

      // But don't let it be zero
      if (current_linear_tolerance == 0.)
        {
          current_linear_tolerance = TOLERANCE * TOLERANCE;
        }

      // At this point newton_iterate is the current guess, and
      // solution is now about to become the NEGATIVE of the next
      // Newton step.

      // Our best initial guess for the solution is zero!
      solution.zero();

      if (!quiet)
        std::cout << "Linear solve starting" << std::endl;

      PAUSE_LOG("solve()", "NewtonSolver");
      // Solve the linear system.  Two cases:
      const std::pair<unsigned int, Real> rval =
        (_system.have_matrix("Preconditioner")) ?
      // 1.) User-supplied preconditioner
        linear_solver->solve (matrix, _system.get_matrix("Preconditioner"),
                              solution, rhs, current_linear_tolerance,
                              max_linear_iterations) :
      // 2.) Use system matrix for the preconditioner
        linear_solver->solve (matrix, solution, rhs,
                              current_linear_tolerance,
                              max_linear_iterations);
      // We may need to localize a parallel solution
      _system.update ();
      RESTART_LOG("solve()", "NewtonSolver");
      // The linear solver may not have fit our constraints exactly
      _system.get_dof_map().enforce_constraints_exactly(_system);

      if (!quiet)
        std::cout << "Linear solve finished, step " << rval.first
                  << ", residual " << rval.second
                  << ", tolerance " << current_linear_tolerance
                  << std::endl;

      // Compute the l2 norm of the nonlinear update
      Real norm_delta = solution.l2_norm();

      if (!quiet)
        std::cout << "Trying full Newton step" << std::endl;
      // Take a full Newton step
      newton_iterate.add (-1., solution);
//      newton_iterate.close();

      // Check residual with full Newton step
      Real steplength = 1.;
      PAUSE_LOG("solve()", "NewtonSolver");
      _system.assembly(true, false);
      RESTART_LOG("solve()", "NewtonSolver");

      rhs.close();
      current_residual = rhs.l2_norm();

      // backtrack if necessary
      if (require_residual_reduction)
        {
          // but don't fiddle around if we've already converged
          if (test_convergence(current_residual, norm_delta))
            {
              if (!quiet)
		print_convergence(l, current_residual, norm_delta);
              break;
            }

          while (current_residual > last_residual)
            {
              // Reduce step size to 1/2, 1/4, etc.
              steplength /= 2.;
              norm_delta /= 2.;
              if (!quiet)
                std::cout << "Shrinking Newton step to "
                          << steplength << std::endl;
              newton_iterate.add (steplength, solution);
//              newton_iterate.close();

              // Check residual with fractional Newton step
              PAUSE_LOG("solve()", "NewtonSolver");
              _system.assembly (true, false);
              RESTART_LOG("solve()", "NewtonSolver");

              rhs.close();
              current_residual = rhs.l2_norm();
              if (!quiet)
                std::cout << "Current Residual: "
                          << current_residual << std::endl;

              if (steplength/2. < minsteplength &&
                  current_residual > last_residual)
                {
                  std::cout << "Inexact Newton step FAILED at step "
                            << l << std::endl;

                  error();
                }
            }
        }

      // Compute the l2 norm of the whole solution
      norm_total = newton_iterate.l2_norm();

      max_solution_norm = std::max(max_solution_norm, norm_total);

      // Print out information for the
      // nonlinear iterations.
      if (!quiet)
        std::cout << "  Nonlinear step: |du|/|u| = "
                  << norm_delta / norm_total
                  << ", |du| = " << norm_delta
                  << std::endl;

      // Terminate the solution iteration if the difference between
      // this iteration and the last is sufficiently small.
      if (!quiet)
        print_convergence(l, current_residual,
                          norm_delta / steplength);
      if (test_convergence(current_residual, norm_delta / steplength))
        {
          break;
        }
      if (l >= max_nonlinear_iterations - 1)
        {
          std::cout << "  Nonlinear solver FAILED TO CONVERGE by step " << l
                    << " with norm " << norm_total
                    << std::endl;
          error();
          continue;
        }
    } // end nonlinear loop

  // Copy the final nonlinear iterate into the current_solution,
  // for other libMesh functions that expect it

  solution = newton_iterate;
//  solution.close();

  // We may need to localize a parallel solution
  _system.update ();

  STOP_LOG("solve()", "NewtonSolver");
}

bool NewtonSolver::test_convergence(Real current_residual,
                                    Real step_norm)
{
  // We haven't converged unless we pass a convergence test
  bool has_converged = false;

  // Is our absolute residual low enough?
  if (current_residual < absolute_residual_tolerance)
    has_converged = true;

  // Is our relative residual low enough?
  if ((current_residual / max_residual_norm) <
      relative_residual_tolerance)
    has_converged = true;

  // Is our absolute Newton step size small enough?
  if (step_norm < absolute_step_tolerance)
    has_converged = true;

  // Is our relative Newton step size small enough?
  if (step_norm / max_solution_norm <
      relative_step_tolerance)
    has_converged = true;

  return has_converged;
}

void NewtonSolver::print_convergence(unsigned int step_num,
                                     Real current_residual,
                                     Real step_norm)
{
  // Is our absolute residual low enough?
  if (current_residual < absolute_residual_tolerance)
    {
      std::cout << "  Nonlinear solver converged, step " << step_num
                << ", residual " << current_residual
                << std::endl;
    }
  else if (absolute_residual_tolerance)
    {
      std::cout << "  Nonlinear solver current_residual "
                << current_residual << " > "
                << (absolute_residual_tolerance) << std::endl;
    }

  // Is our relative residual low enough?
  if ((current_residual / max_residual_norm) <
      relative_residual_tolerance)
    {
      std::cout << "  Nonlinear solver converged, step " << step_num
                << ", residual reduction "
                << current_residual / max_residual_norm
                << " < " << relative_residual_tolerance
                << std::endl;
    }
  else if (relative_residual_tolerance)
    {
      if (!quiet)
        std::cout << "  Nonlinear solver relative residual "
                  << (current_residual / max_residual_norm)
                  << " > " << relative_residual_tolerance
                  << std::endl;
    }

  // Is our absolute Newton step size small enough?
  if (step_norm < absolute_step_tolerance)
    {
      std::cout << "  Nonlinear solver converged, step " << step_num
                << ", absolute step size "
                << step_norm
                << " < " << absolute_step_tolerance
                << std::endl;
    }
  else if (absolute_step_tolerance)
    {
      std::cout << "  Nonlinear solver absolute step size "
                << step_norm
                << " > " << absolute_step_tolerance
                << std::endl;
    }

  // Is our relative Newton step size small enough?
  if (step_norm / max_solution_norm <
      relative_step_tolerance)
    {
      std::cout << "  Nonlinear solver converged, step " << step_num
                << ", relative step size "
                << (step_norm / max_solution_norm)
                << " < " << relative_step_tolerance
                << std::endl;
    }
  else if (relative_step_tolerance)
    {
      std::cout << "  Nonlinear solver relative step size "
                << (step_norm / max_solution_norm)
                << " > " << relative_step_tolerance
                << std::endl;
    }
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    TestPassArrays.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
#include "vtkPassArrays.h"

#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkFieldData.h"
#include "vtkIntArray.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkTable.h"

#include "vtkSmartPointer.h"
#define VTK_CREATE(type, name) \
  vtkSmartPointer<type> name = vtkSmartPointer<type>::New()

int TestPassArrays(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
{
  VTK_CREATE(vtkPassArrays, pass);

  cerr << "Creating a simple polydata ..." << endl;
  VTK_CREATE(vtkPolyData, pd);
  VTK_CREATE(vtkIntArray, col1);
  col1->SetName("column1");
  VTK_CREATE(vtkIntArray, col2);
  col2->SetName("column2");
  VTK_CREATE(vtkCellArray, cells);
  VTK_CREATE(vtkPoints, pts);
  for (vtkIdType i = 0; i < 10; i++)
    {
    col1->InsertNextValue(i);
    col2->InsertNextValue(-i);
    pts->InsertNextPoint(0, 0, 0);
    cells->InsertNextCell(1, &i);
    }
  pd->SetPoints(pts);
  pd->SetVerts(cells);
  vtkCellData* cellData = pd->GetCellData();
  cellData->AddArray(col1);
  cellData->AddArray(col2);
  vtkPointData* pointData = pd->GetPointData();
  pointData->AddArray(col1);
  pointData->AddArray(col2);
  vtkFieldData* fieldData = pd->GetFieldData();
  fieldData->AddArray(col1);
  fieldData->AddArray(col2);
  cerr << "... done" << endl;

  int errors = 0;
  pass->SetInput(pd);

  for (int type = 0; type < 3; type++)
    {
    for (int removeArrays = 0; removeArrays <= 1; removeArrays++)
      {
      for (int useFieldTypes = 0; useFieldTypes <= 1; useFieldTypes++)
        {
        cerr << "Passing a column from field type " << type << " ..." << endl;
        pass->ClearArrays();
        pass->AddArray(type, "column1");

        cerr << "RemoveArrays flag is " << removeArrays << endl;
        pass->SetRemoveArrays(removeArrays);

        cerr << "UseFieldTypes flag is " << useFieldTypes << endl;
        pass->SetUseFieldTypes(useFieldTypes);
        pass->ClearFieldTypes();
        int processType = (type+1)%3;
        cerr << "FieldType is " << processType << endl;
        pass->AddFieldType(processType);

        pass->Update();
        vtkPolyData* out = vtkPolyData::SafeDownCast(pass->GetOutput());
        cerr << "... done" << endl;

        cerr << "Checking output ..." << endl;
        vtkFieldData* outAttrib = out->GetAttributesAsFieldData(type);
        vtkIntArray* out1 = vtkIntArray::SafeDownCast(outAttrib->GetAbstractArray("column1"));
        vtkIntArray* out2 = vtkIntArray::SafeDownCast(outAttrib->GetAbstractArray("column2"));
        if (useFieldTypes)
          {
          if (!out1 || !out2)
            {
            ++errors;
            cerr << "ERROR: Output arrays should not have been touched" << endl;
            }
          if (!removeArrays && out->GetAttributesAsFieldData(processType)->GetNumberOfArrays() != 0)
            {
            ++errors;
            cerr << "ERROR: Processed field data should have been cleared" << endl;
            }
          if (removeArrays && out->GetAttributesAsFieldData(processType)->GetNumberOfArrays() != 2)
            {
            ++errors;
            cerr << "ERROR: Processed field data should remain the same" << endl;
            }
          }
        else
          {
          if (removeArrays && out1)
            {
            ++errors;
            cerr << "ERROR: Array output1 should have been removed but it wasn't" << endl;
            }
          if (!removeArrays && !out1)
            {
            ++errors;
            cerr << "ERROR: Array output1 should have been passed but it wasn't" << endl;
            }
          if (removeArrays && !out2)
            {
            ++errors;
            cerr << "ERROR: Array output2 should have been passed but it wasn't" << endl;
            }
          if (!removeArrays && out2)
            {
            ++errors;
            cerr << "ERROR: Array output2 should have been removed but it wasn't" << endl;
            }
          }
        for (vtkIdType j = 0; j < 10; j++)
          {
          if (out1 && out1->GetValue(j) != col1->GetValue(j))
            {
            errors++;
            cerr << "ERROR: column1 output does not match input "
                 << out1->GetValue(j) << "!=" << col1->GetValue(j)
                 << " for field type " << type << endl;
            break;
            }
          if (out2 && out2->GetValue(j) != col2->GetValue(j))
            {
            errors++;
            cerr << "ERROR: column2 output does not match input "
                 << out2->GetValue(j) << "!=" << col2->GetValue(j)
                 << " for field type " << type << endl;
            break;
            }
          }
        cerr << "... done" << endl;
        }
      }
    }

  cerr << errors << " errors" << endl;
  return errors;
}

<commit_msg>COMP: More warnings.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    TestPassArrays.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
#include "vtkPassArrays.h"

#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkFieldData.h"
#include "vtkIntArray.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkTable.h"

#include "vtkSmartPointer.h"
#define VTK_CREATE(type, name) \
  vtkSmartPointer<type> name = vtkSmartPointer<type>::New()

int TestPassArrays(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
{
  VTK_CREATE(vtkPassArrays, pass);

  cerr << "Creating a simple polydata ..." << endl;
  VTK_CREATE(vtkPolyData, pd);
  VTK_CREATE(vtkIntArray, col1);
  col1->SetName("column1");
  VTK_CREATE(vtkIntArray, col2);
  col2->SetName("column2");
  VTK_CREATE(vtkCellArray, cells);
  VTK_CREATE(vtkPoints, pts);
  for (vtkIdType i = 0; i < 10; i++)
    {
    col1->InsertNextValue(i);
    col2->InsertNextValue(-i);
    pts->InsertNextPoint(0, 0, 0);
    cells->InsertNextCell(1, &i);
    }
  pd->SetPoints(pts);
  pd->SetVerts(cells);
  vtkCellData* cellData = pd->GetCellData();
  cellData->AddArray(col1);
  cellData->AddArray(col2);
  vtkPointData* pointData = pd->GetPointData();
  pointData->AddArray(col1);
  pointData->AddArray(col2);
  vtkFieldData* fieldData = pd->GetFieldData();
  fieldData->AddArray(col1);
  fieldData->AddArray(col2);
  cerr << "... done" << endl;

  int errors = 0;
  pass->SetInput(pd);

  for (int type = 0; type < 3; type++)
    {
    for (int removeArrays = 0; removeArrays <= 1; removeArrays++)
      {
      for (int useFieldTypes = 0; useFieldTypes <= 1; useFieldTypes++)
        {
        cerr << "Passing a column from field type " << type << " ..." << endl;
        pass->ClearArrays();
        pass->AddArray(type, "column1");

        cerr << "RemoveArrays flag is " << removeArrays << endl;
        pass->SetRemoveArrays(static_cast<bool>(removeArrays));

        cerr << "UseFieldTypes flag is " << useFieldTypes << endl;
        pass->SetUseFieldTypes(static_cast<bool>(useFieldTypes));
        pass->ClearFieldTypes();
        int processType = (type+1)%3;
        cerr << "FieldType is " << processType << endl;
        pass->AddFieldType(processType);

        pass->Update();
        vtkPolyData* out = vtkPolyData::SafeDownCast(pass->GetOutput());
        cerr << "... done" << endl;

        cerr << "Checking output ..." << endl;
        vtkFieldData* outAttrib = out->GetAttributesAsFieldData(type);
        vtkIntArray* out1 = vtkIntArray::SafeDownCast(outAttrib->GetAbstractArray("column1"));
        vtkIntArray* out2 = vtkIntArray::SafeDownCast(outAttrib->GetAbstractArray("column2"));
        if (useFieldTypes)
          {
          if (!out1 || !out2)
            {
            ++errors;
            cerr << "ERROR: Output arrays should not have been touched" << endl;
            }
          if (!removeArrays && out->GetAttributesAsFieldData(processType)->GetNumberOfArrays() != 0)
            {
            ++errors;
            cerr << "ERROR: Processed field data should have been cleared" << endl;
            }
          if (removeArrays && out->GetAttributesAsFieldData(processType)->GetNumberOfArrays() != 2)
            {
            ++errors;
            cerr << "ERROR: Processed field data should remain the same" << endl;
            }
          }
        else
          {
          if (removeArrays && out1)
            {
            ++errors;
            cerr << "ERROR: Array output1 should have been removed but it wasn't" << endl;
            }
          if (!removeArrays && !out1)
            {
            ++errors;
            cerr << "ERROR: Array output1 should have been passed but it wasn't" << endl;
            }
          if (removeArrays && !out2)
            {
            ++errors;
            cerr << "ERROR: Array output2 should have been passed but it wasn't" << endl;
            }
          if (!removeArrays && out2)
            {
            ++errors;
            cerr << "ERROR: Array output2 should have been removed but it wasn't" << endl;
            }
          }
        for (vtkIdType j = 0; j < 10; j++)
          {
          if (out1 && out1->GetValue(j) != col1->GetValue(j))
            {
            errors++;
            cerr << "ERROR: column1 output does not match input "
                 << out1->GetValue(j) << "!=" << col1->GetValue(j)
                 << " for field type " << type << endl;
            break;
            }
          if (out2 && out2->GetValue(j) != col2->GetValue(j))
            {
            errors++;
            cerr << "ERROR: column2 output does not match input "
                 << out2->GetValue(j) << "!=" << col2->GetValue(j)
                 << " for field type " << type << endl;
            break;
            }
          }
        cerr << "... done" << endl;
        }
      }
    }

  cerr << errors << " errors" << endl;
  return errors;
}

<|endoftext|>


<commit_before>#ifndef __STAN__MCMC__MCMCBASE__HPP__
#define __STAN__MCMC__MCMCBASE__HPP__

#include <fstream>
#include <vector>

namespace stan {

  namespace mcmc {

    class sample {

    private:

      std::vector<double> _cont_params; // Continuous coordinates of sample
      std::vector<int> _disc_params;    // Discrete coordinates of sample
      double _log_prob;                 // Log probability of sample
      double _accept_stat;              // Acceptance statistic of transition

    public:

      sample(const std::vector<double>& q,
             const std::vector<int>& r,
             double log_prob,
             double stat) :
        _cont_params(q),
        _disc_params(r),
        _log_prob(log_prob),
        _accept_stat(stat) {}

      virtual ~sample() {} // No-op

      inline int size_cont() const {
        return _cont_params.size();
      }

      inline double cont_params(int k) const {
        return _cont_params[k];
      }

      inline void cont_params(std::vector<double>& x) const {
        x = _cont_params;
      }

      inline const std::vector<double>& cont_params() const {
        return _cont_params;
      }

      inline int size_disc() const {
        return _disc_params.size();
      }

      inline int disc_params(int k) const {
        return _disc_params[k];
      }

      inline void disc_params(std::vector<int>& n) const {
        n = _disc_params;
      }

      inline const std::vector<int>& disc_params() const {
        return _disc_params;
      }

      inline double log_prob() const {
        return _log_prob;
      }

      inline double accept_stat() const {
        return _accept_stat;
      }

    };

    class mcmc_sampler {
    public:

      virtual sample transition(sample& init_sample) = 0;

      virtual void write_sampler_param_names(std::ostream& o) {};

      virtual void write_sampler_params(std::ostream& o) {};

      virtual void get_sampler_param_names(std::vector<std::string>& names) {};

      virtual void get_sampler_params(std::vector<double>& values) {};

    };

  } // mcmc

} // stan

#endif

<commit_msg>Removed old file<commit_after><|endoftext|>