<commit_before>

#include <thread>
#include <vector>

#include <locale.h>
#include <stdio.h>
#include "link-grammar/link-includes.h"

static void parse_sents(Dictionary dict, Parse_Options opts, int thread_id, int niter)
{
	const char *sents[] = {
		"Frank felt vindicated when his long time friend Bill revealed that he was the winner of the competition.",
		"Logorrhea, or excessive and often incoherent talkativeness or wordiness, is a social disease.",
		"He obtained the lease of the manor of Great Burstead Grange (near East Horndon) from the Abbey of Stratford Langthorne, and purchased the manor of Bayhouse in West Thurrock.",
		"We ate popcorn and watched movies on TV for three days.",
		"Sweat stood on his brow, fury was bright in his one good eye.",
		"One of the things you do when you stop your bicycle is apply the brake."
// "под броню боевого робота устремились потоки энергии.",
// "через четверть часа здесь будет полно полицейских."
	};

	int nsents = sizeof(sents) / sizeof(const char *);
	for (int i=0; i < nsents; ++i)
	{
		Sentence sent = sentence_create(sents[i], dict);
		sentence_split(sent, opts);
		int num_linkages = sentence_parse(sent, opts);
		if (num_linkages > 0) {
			Linkage linkage = linkage_create(0, sent, opts);
			char * diagram = linkage_print_diagram(linkage, true, 800);
			linkage_free_diagram(diagram);
			linkage_delete(linkage);
		}
		sentence_delete(sent);
	}
}

int main(int argc, char* argv[])
{
	setlocale(LC_ALL, "en_US.UTF-8");
	Parse_Options opts = parse_options_create();
	// Dictionary dict = dictionary_create_lang("ru");
	Dictionary dict = dictionary_create_lang("en");
	if (!dict) {
		printf ("Fatal error: Unable to open the dictionary\n");
		return 1;
	}

	int n_threads = 10;
	int niter = 100;
	std::vector<std::thread> thread_pool;
	for (int i=0; i < n_threads; i++) {
		thread_pool.push_back(std::thread(parse_sents, dict, opts, i, niter));
	}

	// Wait for all threads to complete
	for (std::thread& t : thread_pool) t.join();

	dictionary_delete(dict);
	parse_options_delete(opts);
	return 0;
}
<commit_msg>reorganize the threading test<commit_after>

#include <thread>
#include <vector>

#include <locale.h>
#include <stdio.h>
#include "link-grammar/link-includes.h"

static void parse_one_sent(Dictionary dict, Parse_Options opts, const char *str)
{
	Sentence sent = sentence_create(str, dict);
	sentence_split(sent, opts);
	int num_linkages = sentence_parse(sent, opts);
	if (0 < num_linkages)
	{
		if (10 < num_linkages) num_linkages = 10;

		for (int li = 0; li<num_linkages; li++)
		{
			Linkage linkage = linkage_create(li, sent, opts);
			char * diagram = linkage_print_diagram(linkage, true, 80);
			linkage_free_diagram(diagram);
			linkage_delete(linkage);
		}
	}
	sentence_delete(sent);
}

static void parse_sents(Dictionary dict, Parse_Options opts, int thread_id, int niter)
{
	const char *sents[] = {
		"Frank felt vindicated when his long time friend Bill revealed that he was the winner of the competition.",
		"Logorrhea, or excessive and often incoherent talkativeness or wordiness, is a social disease.",
		"He obtained the lease of the manor of Great Burstead Grange (near East Horndon) from the Abbey of Stratford Langthorne, and purchased the manor of Bayhouse in West Thurrock.",
		"We ate popcorn and watched movies on TV for three days.",
		"Sweat stood on his brow, fury was bright in his one good eye.",
		"One of the things you do when you stop your bicycle is apply the brake."
// "под броню боевого робота устремились потоки энергии.",
// "через четверть часа здесь будет полно полицейских."
	};

	int nsents = sizeof(sents) / sizeof(const char *);

	for (int j=0; j<niter; j++)
	{
		for (int i=0; i < nsents; ++i)
		{
			parse_one_sent(dict, opts, sents[i]);
		}
	}
}

int main(int argc, char* argv[])
{
	setlocale(LC_ALL, "en_US.UTF-8");
	Parse_Options opts = parse_options_create();
	// Dictionary dict = dictionary_create_lang("ru");
	Dictionary dict = dictionary_create_lang("en");
	if (!dict) {
		printf ("Fatal error: Unable to open the dictionary\n");
		return 1;
	}

	int n_threads = 10;
	int niter = 100;

	printf("Creating %d threads, each running %d iterations\n",
		 n_threads, niter);
	std::vector<std::thread> thread_pool;
	for (int i=0; i < n_threads; i++) {
		thread_pool.push_back(std::thread(parse_sents, dict, opts, i, niter));
	}

	// Wait for all threads to complete
	for (std::thread& t : thread_pool) t.join();

	dictionary_delete(dict);
	parse_options_delete(opts);
	return 0;
}
<|endoftext|>


<commit_before>//===--- RawSILInstLowering.cpp -------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "raw-sil-inst-lowering"
#include "swift/SIL/SILBuilder.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"
#include "llvm/ADT/Statistic.h"

STATISTIC(numAssignRewritten, "Number of assigns rewritten");

using namespace swift;

/// Emit the sequence that an assign instruction lowers to once we know
/// if it is an initialization or an assignment.  If it is an assignment,
/// a live-in value can be provided to optimize out the reload.
static void lowerAssignInstruction(SILBuilderWithScope &b, AssignInst *inst) {
  LLVM_DEBUG(llvm::dbgs() << "  *** Lowering [isInit="
                          << unsigned(inst->getOwnershipQualifier())
                          << "]: " << *inst << "\n");

  ++numAssignRewritten;

  SILValue src = inst->getSrc();
  SILValue dest = inst->getDest();
  SILLocation loc = inst->getLoc();
  AssignOwnershipQualifier qualifier = inst->getOwnershipQualifier();

  // Unknown qualifier is considered unprocessed. Just lower it as [reassign],
  // but if the destination type is trivial, treat it as [init].
  //
  // Unknown should not be lowered because definite initialization should
  // always set an initialization kind for assign instructions, but there exists
  // some situations where SILGen doesn't generate a mark_uninitialized
  // instruction for a full mark_uninitialized. Thus definite initialization
  // doesn't set an initialization kind for some assign instructions.
  //
  // TODO: Fix SILGen so that this is an assert preventing the lowering of
  //       Unknown init kind.
  if (qualifier == AssignOwnershipQualifier::Unknown)
    qualifier = AssignOwnershipQualifier::Reassign;

  if (qualifier == AssignOwnershipQualifier::Init ||
      inst->getDest()->getType().isTrivial(*inst->getFunction())) {

    // If this is an initialization, or the storage type is trivial, we
    // can just replace the assignment with a store.
    assert(qualifier != AssignOwnershipQualifier::Reinit);
    b.createTrivialStoreOr(loc, src, dest, StoreOwnershipQualifier::Init);
    inst->eraseFromParent();
    return;
  }

  if (qualifier == AssignOwnershipQualifier::Reinit) {
    // We have a case where a convenience initializer on a class
    // delegates to a factory initializer from a protocol extension.
    // Factory initializers give us a whole new instance, so the existing
    // instance, which has not been initialized and never will be, must be
    // freed using dealloc_partial_ref.
    SILValue pointer = b.createLoad(loc, dest, LoadOwnershipQualifier::Take);
    b.createStore(loc, src, dest, StoreOwnershipQualifier::Init);

    auto metatypeTy = CanMetatypeType::get(
        dest->getType().getASTType(), MetatypeRepresentation::Thick);
    auto silMetatypeTy = SILType::getPrimitiveObjectType(metatypeTy);
    SILValue metatype = b.createValueMetatype(loc, silMetatypeTy, pointer);

    b.createDeallocPartialRef(loc, pointer, metatype);
    inst->eraseFromParent();
    return;
  }

  assert(qualifier == AssignOwnershipQualifier::Reassign);
  // Otherwise, we need to replace the assignment with a store [assign] which
  // lowers to the load/store/release dance. Note that the new value is already
  // considered to be retained (by the semantics of the storage type),
  // and we're transferring that ownership count into the destination.

  b.createStore(loc, src, dest, StoreOwnershipQualifier::Assign);
  inst->eraseFromParent();
}

/// Construct the argument list for the assign_by_wrapper initializer or setter.
///
/// Usually this is only a single value and a single argument, but in case of
/// a tuple, the initializer/setter expect the tuple elements as separate
/// arguments. The purpose of this function is to recursively visit tuple
/// elements and add them to the argument list \p arg.
static void getAssignByWrapperArgsRecursively(SmallVectorImpl<SILValue> &args,
    SILValue src, unsigned &argIdx, const SILFunctionConventions &convention,
    SILBuilder &forProjections, SILBuilder &forCleanup) {

  SILLocation loc = (*forProjections.getInsertionPoint()).getLoc();
  SILType srcTy = src->getType();
  if (auto tupleTy = srcTy.getAs<TupleType>()) {
    // In case the source is a tuple, we have to destructure the tuple and pass
    // the tuple elements separately.
    if (srcTy.isAddress()) {
      for (unsigned idx = 0, n = tupleTy->getNumElements(); idx < n; ++idx) {
        auto *TEA = forProjections.createTupleElementAddr(loc, src, idx);
        getAssignByWrapperArgsRecursively(args, TEA, argIdx, convention,
          forProjections, forCleanup);
      }
    } else {
      auto *DTI = forProjections.createDestructureTuple(loc, src);
      for (SILValue elmt : DTI->getAllResults()) {
        getAssignByWrapperArgsRecursively(args, elmt, argIdx, convention,
          forProjections, forCleanup);
      }
    }
    return;
  }
  assert(argIdx < convention.getNumSILArguments() &&
         "initializer or setter has too few arguments");

  SILArgumentConvention argConv = convention.getSILArgumentConvention(argIdx);
  if (srcTy.isAddress() && !argConv.isIndirectConvention()) {
    // In case of a tuple where one element is loadable, but the other is
    // address only, we get the whole tuple as address.
    // For the loadable element, the argument is passed directly, but the
    // tuple element is in memory. For this case we have to insert a load.
    src = forProjections.createTrivialLoadOr(loc, src,
                                             LoadOwnershipQualifier::Take);
  }
  switch (argConv) {
    case SILArgumentConvention::Indirect_In_Guaranteed:
      forCleanup.createDestroyAddr(loc, src);
      break;
    case SILArgumentConvention::Direct_Guaranteed:
      forCleanup.createDestroyValue(loc, src);
      break;
    case SILArgumentConvention::Direct_Unowned:
    case SILArgumentConvention::Indirect_In:
    case SILArgumentConvention::Indirect_In_Constant:
    case SILArgumentConvention::Direct_Owned:
      break;
    case SILArgumentConvention::Indirect_Inout:
    case SILArgumentConvention::Indirect_InoutAliasable:
    case SILArgumentConvention::Indirect_Out:
      llvm_unreachable("wrong convention for setter/initializer src argument");
  }
  args.push_back(src);
  ++argIdx;
}

static void getAssignByWrapperArgs(SmallVectorImpl<SILValue> &args,
            SILValue src, const SILFunctionConventions &convention,
            SILBuilder &forProjections, SILBuilder &forCleanup) {
  unsigned argIdx = convention.getSILArgIndexOfFirstParam();
  getAssignByWrapperArgsRecursively(args, src, argIdx, convention,
                              forProjections, forCleanup);
  assert(argIdx == convention.getNumSILArguments() &&
         "initializer or setter has too many arguments");
}

static void lowerAssignByWrapperInstruction(SILBuilderWithScope &b,
                                             AssignByWrapperInst *inst,
                            SmallVectorImpl<BeginAccessInst *> &accessMarkers) {
  LLVM_DEBUG(llvm::dbgs() << "  *** Lowering [isInit="
             << unsigned(inst->getOwnershipQualifier())
             << "]: " << *inst << "\n");

  ++numAssignRewritten;

  SILValue src = inst->getSrc();
  SILValue dest = inst->getDest();
  SILLocation loc = inst->getLoc();
  SILBuilderWithScope forCleanup(std::next(inst->getIterator()));

  switch (inst->getAssignDestination()) {
    case AssignByWrapperInst::Destination::BackingWrapper: {
      SILValue initFn = inst->getInitializer();
      CanSILFunctionType fTy = initFn->getType().castTo<SILFunctionType>();
      SILFunctionConventions convention(fTy, inst->getModule());
      SmallVector<SILValue, 4> args;
      if (convention.hasIndirectSILResults()) {
        args.push_back(dest);
        getAssignByWrapperArgs(args, src, convention, b, forCleanup);
        b.createApply(loc, initFn, SubstitutionMap(), args);
      } else {
        getAssignByWrapperArgs(args, src, convention, b, forCleanup);
        SILValue wrappedSrc = b.createApply(loc, initFn, SubstitutionMap(),
                                            args);
        if (inst->getOwnershipQualifier() == AssignOwnershipQualifier::Init ||
            inst->getDest()->getType().isTrivial(*inst->getFunction())) {
          b.createTrivialStoreOr(loc, wrappedSrc, dest, StoreOwnershipQualifier::Init);
        } else {
          b.createStore(loc, wrappedSrc, dest, StoreOwnershipQualifier::Assign);
        }
      }
      // TODO: remove the unused setter function, which usually is a dead
      // partial_apply.
      break;
    }
    case AssignByWrapperInst::Destination::WrappedValue: {
      SILValue setterFn = inst->getSetter();
      CanSILFunctionType fTy = setterFn->getType().castTo<SILFunctionType>();
      SILFunctionConventions convention(fTy, inst->getModule());
      assert(!convention.hasIndirectSILResults());
      SmallVector<SILValue, 4> args;
      getAssignByWrapperArgs(args, src, convention, b, forCleanup);
      b.createApply(loc, setterFn, SubstitutionMap(), args);

      // The destination address is not used. Remove it if it is a dead access
      // marker. This is important, because also the setter function contains
      // access marker. In case those markers are dynamic it would cause a
      // nested access violation.
      if (auto *BA = dyn_cast<BeginAccessInst>(dest))
        accessMarkers.push_back(BA);
      // TODO: remove the unused init function, which usually is a dead
      // partial_apply.
      break;
    }
  }
  inst->eraseFromParent();
}

static void deleteDeadAccessMarker(BeginAccessInst *BA) {
  SmallVector<SILInstruction *, 4> Users;
  for (Operand *Op : BA->getUses()) {
    SILInstruction *User = Op->getUser();
    if (!isa<EndAccessInst>(User))
      return;

    Users.push_back(User);
  }
  for (SILInstruction *User: Users) {
    User->eraseFromParent();
  }
  BA->eraseFromParent();
}

/// lowerRawSILOperations - There are a variety of raw-sil instructions like
/// 'assign' that are only used by this pass.  Now that definite initialization
/// checking is done, remove them.
static bool lowerRawSILOperations(SILFunction &fn) {
  bool changed = false;

  for (auto &bb : fn) {
    SmallVector<BeginAccessInst *, 8> accessMarkers;

    auto i = bb.begin(), e = bb.end();
    while (i != e) {
      SILInstruction *inst = &*i;
      ++i;

      // Lower 'assign' depending on initialization kind defined by definite
      // initialization.
      //
      // * Unknown is considered unprocessed and is treated as [reassign] or
      //   [init] if the destination type is trivial.
      // * Init becomes a store [init] or a store [trivial] if the destination's
      //   type is trivial.
      // * Reinit becomes a load [take], store [init], and a
      //   dealloc_partial_ref.
      // * Reassign becomes a store [assign].
      if (auto *ai = dyn_cast<AssignInst>(inst)) {
        SILBuilderWithScope b(ai);
        lowerAssignInstruction(b, ai);
        // Assign lowering may split the block. If it did,
        // reset our iteration range to the block after the insertion.
        if (b.getInsertionBB() != &bb)
          i = e;
        changed = true;
        continue;
      }

      if (auto *ai = dyn_cast<AssignByWrapperInst>(inst)) {
        SILBuilderWithScope b(ai);
        lowerAssignByWrapperInstruction(b, ai, accessMarkers);
        changed = true;
        continue;
      }

      // mark_uninitialized just becomes a noop, resolving to its operand.
      if (auto *mui = dyn_cast<MarkUninitializedInst>(inst)) {
        mui->replaceAllUsesWith(mui->getOperand());
        mui->eraseFromParent();
        changed = true;
        continue;
      }

      // mark_function_escape just gets zapped.
      if (isa<MarkFunctionEscapeInst>(inst)) {
        inst->eraseFromParent();
        changed = true;
        continue;
      }
    }
    for (BeginAccessInst *BA : accessMarkers) {
      deleteDeadAccessMarker(BA);
    }
  }
  return changed;
}

//===----------------------------------------------------------------------===//
//                            Top Level Entrypoint
//===----------------------------------------------------------------------===//

namespace {

class RawSILInstLowering : public SILFunctionTransform {
  void run() override {
    // Do not try to relower raw instructions in canonical SIL. There won't be
    // any there.
    if (getFunction()->wasDeserializedCanonical()) {
      return;
    }

    // Lower raw-sil only instructions used by this pass, like "assign".
    if (lowerRawSILOperations(*getFunction()))
      invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
  }
};

} // end anonymous namespace

SILTransform *swift::createRawSILInstLowering() {
  return new RawSILInstLowering();
}
<commit_msg>RawSILInstLowering: delete an unused partial_apply when lowering assign_by_wrapper<commit_after>//===--- RawSILInstLowering.cpp -------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "raw-sil-inst-lowering"
#include "swift/SIL/SILBuilder.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
#include "llvm/ADT/Statistic.h"

STATISTIC(numAssignRewritten, "Number of assigns rewritten");

using namespace swift;

/// Emit the sequence that an assign instruction lowers to once we know
/// if it is an initialization or an assignment.  If it is an assignment,
/// a live-in value can be provided to optimize out the reload.
static void lowerAssignInstruction(SILBuilderWithScope &b, AssignInst *inst) {
  LLVM_DEBUG(llvm::dbgs() << "  *** Lowering [isInit="
                          << unsigned(inst->getOwnershipQualifier())
                          << "]: " << *inst << "\n");

  ++numAssignRewritten;

  SILValue src = inst->getSrc();
  SILValue dest = inst->getDest();
  SILLocation loc = inst->getLoc();
  AssignOwnershipQualifier qualifier = inst->getOwnershipQualifier();

  // Unknown qualifier is considered unprocessed. Just lower it as [reassign],
  // but if the destination type is trivial, treat it as [init].
  //
  // Unknown should not be lowered because definite initialization should
  // always set an initialization kind for assign instructions, but there exists
  // some situations where SILGen doesn't generate a mark_uninitialized
  // instruction for a full mark_uninitialized. Thus definite initialization
  // doesn't set an initialization kind for some assign instructions.
  //
  // TODO: Fix SILGen so that this is an assert preventing the lowering of
  //       Unknown init kind.
  if (qualifier == AssignOwnershipQualifier::Unknown)
    qualifier = AssignOwnershipQualifier::Reassign;

  if (qualifier == AssignOwnershipQualifier::Init ||
      inst->getDest()->getType().isTrivial(*inst->getFunction())) {

    // If this is an initialization, or the storage type is trivial, we
    // can just replace the assignment with a store.
    assert(qualifier != AssignOwnershipQualifier::Reinit);
    b.createTrivialStoreOr(loc, src, dest, StoreOwnershipQualifier::Init);
    inst->eraseFromParent();
    return;
  }

  if (qualifier == AssignOwnershipQualifier::Reinit) {
    // We have a case where a convenience initializer on a class
    // delegates to a factory initializer from a protocol extension.
    // Factory initializers give us a whole new instance, so the existing
    // instance, which has not been initialized and never will be, must be
    // freed using dealloc_partial_ref.
    SILValue pointer = b.createLoad(loc, dest, LoadOwnershipQualifier::Take);
    b.createStore(loc, src, dest, StoreOwnershipQualifier::Init);

    auto metatypeTy = CanMetatypeType::get(
        dest->getType().getASTType(), MetatypeRepresentation::Thick);
    auto silMetatypeTy = SILType::getPrimitiveObjectType(metatypeTy);
    SILValue metatype = b.createValueMetatype(loc, silMetatypeTy, pointer);

    b.createDeallocPartialRef(loc, pointer, metatype);
    inst->eraseFromParent();
    return;
  }

  assert(qualifier == AssignOwnershipQualifier::Reassign);
  // Otherwise, we need to replace the assignment with a store [assign] which
  // lowers to the load/store/release dance. Note that the new value is already
  // considered to be retained (by the semantics of the storage type),
  // and we're transferring that ownership count into the destination.

  b.createStore(loc, src, dest, StoreOwnershipQualifier::Assign);
  inst->eraseFromParent();
}

/// Construct the argument list for the assign_by_wrapper initializer or setter.
///
/// Usually this is only a single value and a single argument, but in case of
/// a tuple, the initializer/setter expect the tuple elements as separate
/// arguments. The purpose of this function is to recursively visit tuple
/// elements and add them to the argument list \p arg.
static void getAssignByWrapperArgsRecursively(SmallVectorImpl<SILValue> &args,
    SILValue src, unsigned &argIdx, const SILFunctionConventions &convention,
    SILBuilder &forProjections, SILBuilder &forCleanup) {

  SILLocation loc = (*forProjections.getInsertionPoint()).getLoc();
  SILType srcTy = src->getType();
  if (auto tupleTy = srcTy.getAs<TupleType>()) {
    // In case the source is a tuple, we have to destructure the tuple and pass
    // the tuple elements separately.
    if (srcTy.isAddress()) {
      for (unsigned idx = 0, n = tupleTy->getNumElements(); idx < n; ++idx) {
        auto *TEA = forProjections.createTupleElementAddr(loc, src, idx);
        getAssignByWrapperArgsRecursively(args, TEA, argIdx, convention,
          forProjections, forCleanup);
      }
    } else {
      auto *DTI = forProjections.createDestructureTuple(loc, src);
      for (SILValue elmt : DTI->getAllResults()) {
        getAssignByWrapperArgsRecursively(args, elmt, argIdx, convention,
          forProjections, forCleanup);
      }
    }
    return;
  }
  assert(argIdx < convention.getNumSILArguments() &&
         "initializer or setter has too few arguments");

  SILArgumentConvention argConv = convention.getSILArgumentConvention(argIdx);
  if (srcTy.isAddress() && !argConv.isIndirectConvention()) {
    // In case of a tuple where one element is loadable, but the other is
    // address only, we get the whole tuple as address.
    // For the loadable element, the argument is passed directly, but the
    // tuple element is in memory. For this case we have to insert a load.
    src = forProjections.createTrivialLoadOr(loc, src,
                                             LoadOwnershipQualifier::Take);
  }
  switch (argConv) {
    case SILArgumentConvention::Indirect_In_Guaranteed:
      forCleanup.createDestroyAddr(loc, src);
      break;
    case SILArgumentConvention::Direct_Guaranteed:
      forCleanup.createDestroyValue(loc, src);
      break;
    case SILArgumentConvention::Direct_Unowned:
    case SILArgumentConvention::Indirect_In:
    case SILArgumentConvention::Indirect_In_Constant:
    case SILArgumentConvention::Direct_Owned:
      break;
    case SILArgumentConvention::Indirect_Inout:
    case SILArgumentConvention::Indirect_InoutAliasable:
    case SILArgumentConvention::Indirect_Out:
      llvm_unreachable("wrong convention for setter/initializer src argument");
  }
  args.push_back(src);
  ++argIdx;
}

static void getAssignByWrapperArgs(SmallVectorImpl<SILValue> &args,
            SILValue src, const SILFunctionConventions &convention,
            SILBuilder &forProjections, SILBuilder &forCleanup) {
  unsigned argIdx = convention.getSILArgIndexOfFirstParam();
  getAssignByWrapperArgsRecursively(args, src, argIdx, convention,
                              forProjections, forCleanup);
  assert(argIdx == convention.getNumSILArguments() &&
         "initializer or setter has too many arguments");
}

static void lowerAssignByWrapperInstruction(SILBuilderWithScope &b,
                                             AssignByWrapperInst *inst,
                            SmallVectorImpl<BeginAccessInst *> &accessMarkers) {
  LLVM_DEBUG(llvm::dbgs() << "  *** Lowering [isInit="
             << unsigned(inst->getOwnershipQualifier())
             << "]: " << *inst << "\n");

  ++numAssignRewritten;

  SILValue src = inst->getSrc();
  SILValue dest = inst->getDest();
  SILLocation loc = inst->getLoc();
  SILBuilderWithScope forCleanup(std::next(inst->getIterator()));
  SingleValueInstruction *closureToDelete = nullptr;

  switch (inst->getAssignDestination()) {
    case AssignByWrapperInst::Destination::BackingWrapper: {
      SILValue initFn = inst->getInitializer();
      CanSILFunctionType fTy = initFn->getType().castTo<SILFunctionType>();
      SILFunctionConventions convention(fTy, inst->getModule());
      SmallVector<SILValue, 4> args;
      if (convention.hasIndirectSILResults()) {
        args.push_back(dest);
        getAssignByWrapperArgs(args, src, convention, b, forCleanup);
        b.createApply(loc, initFn, SubstitutionMap(), args);
      } else {
        getAssignByWrapperArgs(args, src, convention, b, forCleanup);
        SILValue wrappedSrc = b.createApply(loc, initFn, SubstitutionMap(),
                                            args);
        if (inst->getOwnershipQualifier() == AssignOwnershipQualifier::Init ||
            inst->getDest()->getType().isTrivial(*inst->getFunction())) {
          b.createTrivialStoreOr(loc, wrappedSrc, dest, StoreOwnershipQualifier::Init);
        } else {
          b.createStore(loc, wrappedSrc, dest, StoreOwnershipQualifier::Assign);
        }
      }
      closureToDelete = dyn_cast<SingleValueInstruction>(inst->getSetter());
      break;
    }
    case AssignByWrapperInst::Destination::WrappedValue: {
      SILValue setterFn = inst->getSetter();
      CanSILFunctionType fTy = setterFn->getType().castTo<SILFunctionType>();
      SILFunctionConventions convention(fTy, inst->getModule());
      assert(!convention.hasIndirectSILResults());
      SmallVector<SILValue, 4> args;
      getAssignByWrapperArgs(args, src, convention, b, forCleanup);
      b.createApply(loc, setterFn, SubstitutionMap(), args);

      // The destination address is not used. Remove it if it is a dead access
      // marker. This is important, because also the setter function contains
      // access marker. In case those markers are dynamic it would cause a
      // nested access violation.
      if (auto *BA = dyn_cast<BeginAccessInst>(dest))
        accessMarkers.push_back(BA);
      closureToDelete = dyn_cast<SingleValueInstruction>(inst->getInitializer());
      break;
    }
  }
  inst->eraseFromParent();
  if (closureToDelete)
    tryDeleteDeadClosure(closureToDelete);
}

static void deleteDeadAccessMarker(BeginAccessInst *BA) {
  SmallVector<SILInstruction *, 4> Users;
  for (Operand *Op : BA->getUses()) {
    SILInstruction *User = Op->getUser();
    if (!isa<EndAccessInst>(User))
      return;

    Users.push_back(User);
  }
  for (SILInstruction *User: Users) {
    User->eraseFromParent();
  }
  BA->eraseFromParent();
}

/// lowerRawSILOperations - There are a variety of raw-sil instructions like
/// 'assign' that are only used by this pass.  Now that definite initialization
/// checking is done, remove them.
static bool lowerRawSILOperations(SILFunction &fn) {
  bool changed = false;

  for (auto &bb : fn) {
    SmallVector<BeginAccessInst *, 8> accessMarkers;

    auto i = bb.begin(), e = bb.end();
    while (i != e) {
      SILInstruction *inst = &*i;
      ++i;

      // Lower 'assign' depending on initialization kind defined by definite
      // initialization.
      //
      // * Unknown is considered unprocessed and is treated as [reassign] or
      //   [init] if the destination type is trivial.
      // * Init becomes a store [init] or a store [trivial] if the destination's
      //   type is trivial.
      // * Reinit becomes a load [take], store [init], and a
      //   dealloc_partial_ref.
      // * Reassign becomes a store [assign].
      if (auto *ai = dyn_cast<AssignInst>(inst)) {
        SILBuilderWithScope b(ai);
        lowerAssignInstruction(b, ai);
        // Assign lowering may split the block. If it did,
        // reset our iteration range to the block after the insertion.
        if (b.getInsertionBB() != &bb)
          i = e;
        changed = true;
        continue;
      }

      if (auto *ai = dyn_cast<AssignByWrapperInst>(inst)) {
        SILBuilderWithScope b(ai);
        lowerAssignByWrapperInstruction(b, ai, accessMarkers);
        changed = true;
        continue;
      }

      // mark_uninitialized just becomes a noop, resolving to its operand.
      if (auto *mui = dyn_cast<MarkUninitializedInst>(inst)) {
        mui->replaceAllUsesWith(mui->getOperand());
        mui->eraseFromParent();
        changed = true;
        continue;
      }

      // mark_function_escape just gets zapped.
      if (isa<MarkFunctionEscapeInst>(inst)) {
        inst->eraseFromParent();
        changed = true;
        continue;
      }
    }
    for (BeginAccessInst *BA : accessMarkers) {
      deleteDeadAccessMarker(BA);
    }
  }
  return changed;
}

//===----------------------------------------------------------------------===//
//                            Top Level Entrypoint
//===----------------------------------------------------------------------===//

namespace {

class RawSILInstLowering : public SILFunctionTransform {
  void run() override {
    // Do not try to relower raw instructions in canonical SIL. There won't be
    // any there.
    if (getFunction()->wasDeserializedCanonical()) {
      return;
    }

    // Lower raw-sil only instructions used by this pass, like "assign".
    if (lowerRawSILOperations(*getFunction()))
      invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
  }
};

} // end anonymous namespace

SILTransform *swift::createRawSILInstLowering() {
  return new RawSILInstLowering();
}
<|endoftext|>


<commit_before>#include <Matrix.hpp>
#include <catch.hpp>
#include <fstream>

SCENARIO("Matrix init", "[init]") {
	GIVEN("The number of lines and columns") {
		auto lines = 36;
		auto columns = 39;

		WHEN("Create instansce of Matrix") {
			Matrix<int> matrix(lines, columns);
			THEN("The number of lines and columns must be preserved") {
				REQUIRE(matrix.GetNumberOfLines() == lines);
				REQUIRE(matrix.GetNumberOfColumns() == columns);
			}
		}
	}
}

SCENARIO("Matrix InitFromFile", "[fill]") {
	Matrix<int> C(3, 1);
	C.InitFromFile("C3x1.txt");
	REQUIRE( C[0][0] == 1 );
	REQUIRE( C[1][0] == 2 );
	REQUIRE( C[2][0] == 0 );
}
SCENARIO("Matrix Output", "[output]") {
	Matrix<int> A(5, 4);
	A.InitFromRandom();
	std::cout << A;
}
SCENARIO("Matrix =", "assignment") {
	Matrix<int> A(3, 3);
	A.InitFromFile("A3x3.txt");
	Matrix<int> B(4, 2);
	B = A;
	for (int i = 0; i < 3; i++){
		for (int j = 0; j < 3; j++){
			REQUIRE( A[i][j] == B[i][j] );
		}
	}
}
SCENARIO("Matrix +", "[addition]") {
	Matrix<int> A(3, 3);
	A.InitFromFile("A3x3.txt");
	Matrix<int> B(3, 3);
	B.InitFromFile("B3x3.txt");
	Matrix<int> expected = Matrix<int>(3, 3);
	expected.InitFromFile("(A3x3)+(B3x3).txt");

	Matrix<int> result = A + B;
	for (int i = 0; i < 3; i++){
		for (int j = 0; j < 3; j++){
			REQUIRE(result[i][j] == expected[i][j]);
		}
	}
}
SCENARIO("Matrix *", "[multiplication]") {
	Matrix<int> A = Matrix<int>(3, 3);
	A.InitFromFile("A3x3.txt");
	Matrix<int> C = Matrix<int>(3, 1);
	C.InitFromFile("C3x1.txt");
	Matrix<int> expected = Matrix<int>(3, 1);
	expected.InitFromFile("(A3x3)(C3x1).txt");

	Matrix<int> result = A * C;
	for (int i = 0; i < 3; i++){
		REQUIRE(result[i][0] == expected[i][0]);
	}
}
SCENARIO("Matrix ==", "[comparsion]"){
	Matrix<int> A = Matrix<int>(3, 3);
	A.InitFromFile("A3x3.txt");
	Matrix<int> C = Matrix<int>(3, 1);
	C.InitFromFile("C3x1.txt");

	REQUIRE(A != C);
	REQUIRE(A == A);
}
SCENARIO("Bad Matrix *", "[badmultiplication]") {
	Matrix<int> A = Matrix<int>(3, 3);
	A.InitFromFile("A3x3.txt");
	Matrix<int> C = Matrix<int>(3, 1);
	C.InitFromFile("C3x1.txt");
	bool exception_flag = false;
	try{
		C * A;
	} catch (...){
		exception_flag = true;
	}
	REQUIRE(exception_flag);
}
SCENARIO("Bad Matrix +", "[badplus") {
	Matrix<int> A = Matrix<int>(3, 3);
	A.InitFromFile("A3x3.txt");
	Matrix<int> C = Matrix<int>(3, 1);
	C.InitFromFile("C3x1.txt");
	bool exception_flag = false;
	try{
		A + C;
	} catch (...){
		exception_flag = true;
	}
	REQUIRE(exception_flag);
}
SCENARIO("Bad >>", "[badfill]"){
	std::cout << "Bad >>";
	Matrix<int> C(4, 5);
	bool exception_flag = false;
	try{
		C.InitFromFile("A8x3.txt");
	} catch (...){
		exception_flag = true;
	}
	REQUIRE(exception_flag);
}
/*SCENARIO("Bad matrix InitFromFile", "[fill]") {
	Matrix<int> C(3, 1);
	bool exception_flag = false;
	try{
		C.InitFromFile("NotAFile");
	} catch (...){
		exception_flag = true;
	}
	REQUIRE(exception_flag);
}
SCENARIO("Bad []", "[badindex]") {
	Matrix<int> C(3, 1);
	bool exception_flag = false;
	try{
		C[1000];
	} catch (...){
		exception_flag = true;
	}
	REQUIRE(exception_flag);
}
*/
<commit_msg>Update init.cpp<commit_after>#include <Matrix.hpp>
#include <catch.hpp>
#include <fstream>

SCENARIO("Matrix init", "[init]") {
	GIVEN("The number of lines and columns") {
		auto lines = 36;
		auto columns = 39;

		WHEN("Create instansce of Matrix") {
			Matrix<int> matrix(lines, columns);
			THEN("The number of lines and columns must be preserved") {
				REQUIRE(matrix.GetNumberOfLines() == lines);
				REQUIRE(matrix.GetNumberOfColumns() == columns);
			}
		}
	}
}

SCENARIO("Matrix InitFromFile", "[fill]") {
	Matrix<int> C(3, 1);
	C.InitFromFile("C3x1.txt");
	REQUIRE( C[0][0] == 1 );
	REQUIRE( C[1][0] == 2 );
	REQUIRE( C[2][0] == 0 );
}
SCENARIO("Matrix Output", "[output]") {
	Matrix<int> A(5, 4);
	A.InitFromRandom();
	std::cout << A;
}
SCENARIO("Matrix =", "assignment") {
	Matrix<int> A(3, 3);
	A.InitFromFile("A3x3.txt");
	Matrix<int> B(4, 2);
	B = A;
	for (int i = 0; i < 3; i++){
		for (int j = 0; j < 3; j++){
			REQUIRE( A[i][j] == B[i][j] );
		}
	}
}
SCENARIO("Matrix +", "[addition]") {
	Matrix<int> A(3, 3);
	A.InitFromFile("A3x3.txt");
	Matrix<int> B(3, 3);
	B.InitFromFile("B3x3.txt");
	Matrix<int> expected = Matrix<int>(3, 3);
	expected.InitFromFile("(A3x3)+(B3x3).txt");

	Matrix<int> result = A + B;
	for (int i = 0; i < 3; i++){
		for (int j = 0; j < 3; j++){
			REQUIRE(result[i][j] == expected[i][j]);
		}
	}
}
SCENARIO("Matrix *", "[multiplication]") {
	Matrix<int> A = Matrix<int>(3, 3);
	A.InitFromFile("A3x3.txt");
	Matrix<int> C = Matrix<int>(3, 1);
	C.InitFromFile("C3x1.txt");
	Matrix<int> expected = Matrix<int>(3, 1);
	expected.InitFromFile("(A3x3)(C3x1).txt");

	Matrix<int> result = A * C;
	for (int i = 0; i < 3; i++){
		REQUIRE(result[i][0] == expected[i][0]);
	}
}
SCENARIO("Matrix ==", "[comparsion]"){
	Matrix<int> A = Matrix<int>(3, 3);
	A.InitFromFile("A3x3.txt");
	Matrix<int> C = Matrix<int>(3, 1);
	C.InitFromFile("C3x1.txt");

	REQUIRE(A != C);
	REQUIRE(A == A);
}
SCENARIO("Bad Matrix *", "[badmultiplication]") {
	Matrix<int> A = Matrix<int>(3, 3);
	A.InitFromFile("A3x3.txt");
	Matrix<int> C = Matrix<int>(3, 1);
	C.InitFromFile("C3x1.txt");
	bool exception_flag = false;
	try{
		C * A;
	} catch (...){
		exception_flag = true;
	}
	REQUIRE(exception_flag);
}
SCENARIO("Bad Matrix +", "[badplus") {
	Matrix<int> A = Matrix<int>(3, 3);
	A.InitFromFile("A3x3.txt");
	Matrix<int> C = Matrix<int>(3, 1);
	C.InitFromFile("C3x1.txt");
	bool exception_flag = false;
	try{
		A + C;
	} catch (...){
		exception_flag = true;
	}
	REQUIRE(exception_flag);
}
SCENARIO("Bad matrix InitFromFile", "[fill]"){
	std::cout << "Bad >>";
	Matrix<int> C(4, 5);
	bool exception_flag = false;
	try{
		C.InitFromFile("A8x3.txt");
	} catch (...){
		exception_flag = true;
	}
	REQUIRE(exception_flag);
}

SCENARIO("Bad []", "[badindex]") {
	Matrix<int> C(3, 1);
	bool exception_flag = false;
	try{
		C[1000];
	} catch (...){
		exception_flag = true;
	}
	REQUIRE(exception_flag);
}

<|endoftext|>


<commit_before>#include <iostream>
#include "protojson.h"
#include "core/assert.h"

namespace
{
  std::string json2field(const rapidjson::Value* json, google::protobuf::Message* msg, const google::protobuf::FieldDescriptor *field)
  {
    const auto* ref = msg->GetReflection();
    const bool repeated = field->is_repeated();
    switch (field->cpp_type())
    {
      case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
      {
        if (json->GetType() != rapidjson::kNumberType)
        {
          return "Not a number";
        }
        if (repeated)
        {
          ref->AddInt32(msg, field, (int32_t) json->GetInt());
        }
        else
        {
          ref->SetInt32(msg, field, (int32_t) json->GetInt());
        }
        break;
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
      {
        if (json->GetType() != rapidjson::kNumberType)
        {
          return "Not a number";
        }
        if (repeated)
        {
          ref->AddUInt32(msg, field, json->GetUint());
        }
        else
        {
          ref->SetUInt32(msg, field, json->GetUint());
        }
        break;
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
      {
        if (json->GetType() != rapidjson::kNumberType)
        {
          return "Not a number";
        }
        if (repeated)
        {
          ref->AddInt64(msg, field, json->GetInt64());
        }
        else
        {
          ref->SetInt64(msg, field, json->GetInt64());
        }
        break;
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
      {
        if (json->GetType() != rapidjson::kNumberType)
        {
          return "Not a number";
        }
        if (repeated)
        {
          ref->AddUInt64(msg, field, json->GetUint64());
        }
        else
        {
          ref->SetUInt64(msg, field, json->GetUint64());
        }
        break;
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
      {
        if (json->GetType() != rapidjson::kNumberType)
        {
          return "Not a number";
        }
        if (repeated)
        {
          ref->AddDouble(msg, field, json->GetDouble());
        }
        else
        {
          ref->SetDouble(msg, field, json->GetDouble());
        }
        break;
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
      {
        if (json->GetType() != rapidjson::kNumberType)
        {
          return "Not a number";
        }
        if (repeated)
        {
          ref->AddFloat(msg, field, json->GetDouble());
        }
        else
        {
          ref->SetFloat(msg, field, json->GetDouble());
        }
        break;
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
      {
        if (json->GetType() != rapidjson::kTrueType && json->GetType() != rapidjson::kFalseType)
        {
          return "Not a bool";
        }
        bool v = json->GetBool();
        if (repeated)
        {
          ref->AddBool(msg, field, v);
        }
        else
        {
          ref->SetBool(msg, field, v);
        }
        break;
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
      {
        if (json->GetType() != rapidjson::kStringType)
        {
          return "Not a string";
        }
        const char* value = json->GetString();
        uint32_t str_size = json->GetStringLength();
        std::string str_value(value, str_size);
        if (field->type() == google::protobuf::FieldDescriptor::TYPE_BYTES)
        {
          if (repeated)
          {
            Assert(false);
            // ref->AddString(msg, field, b64_decode(str_value));
          }
          else
          {
            Assert(false);
            // ref->SetString(msg, field, b64_decode(str_value));
          }
        }
        else
        {
          if (repeated)
          {
            ref->AddString(msg, field, str_value);
          }
          else
          {
            ref->SetString(msg, field, str_value);
          }
        }
        break;
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
      {
        google::protobuf::Message *mf = (repeated) ? ref->AddMessage(msg, field) : ref->MutableMessage(msg, field);
        return protojson::ToProto(*json, mf);
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
      {
        const auto* ed = field->enum_type();
        const google::protobuf::EnumValueDescriptor* ev = nullptr;
        if (json->GetType() == rapidjson::kNumberType)
        {
          ev = ed->FindValueByNumber(json->GetInt());
        }
        else if (json->GetType() == rapidjson::kStringType)
        {
          ev = ed->FindValueByName(json->GetString());
        }
        else return "Not an integer or string";
        if (!ev)
          return "Enum value not found";
        if (repeated)
        {
          ref->AddEnum(msg, field, ev);
        }
        else
        {
          ref->SetEnum(msg, field, ev);
        }
        break;
      }
      default:
        break;
    }
    return "";
  }
}

namespace protojson
{
  std::string ToProto(const rapidjson::Value& json, google::protobuf::Message* msg)
  {
    if (json.GetType() != rapidjson::kObjectType)
    {
      return "JSON root is not a object";
    }
    const  auto* d = msg->GetDescriptor();
    const auto* ref = msg->GetReflection();
    if (d == nullptr || ref == nullptr)
    {
      return "Protobuf object has no reflection";
    }

    for (rapidjson::Value::ConstMemberIterator itr = json.MemberBegin(); itr != json.MemberEnd(); ++itr)
    {
      const char* name = itr->name.GetString();
      const auto* field = d->FindFieldByName(name);
      if (field == nullptr)
        field = ref->FindKnownExtensionByName(name);
      if (field == nullptr) {
        std::cerr << "Failed to find field " << name << " in json\n";
        continue; // todo: we should not fail here, instead write this value into an unknown field
      }
      if (itr->value.GetType() == rapidjson::kNullType) {
        ref->ClearField(msg, field);
        continue;
      }
      if (field->is_repeated())
      {
        if (itr->value.GetType() != rapidjson::kArrayType) {
          return "Protobuf is repeated but json didnt specify an array";
        }
        for (rapidjson::Value::ConstValueIterator ait = itr->value.Begin(); ait != itr->value.End(); ++ait)
        {
          const auto ret = json2field(ait, msg, field);
          if (!ret.empty())
          {
            return ret;
          }
        }
      }
      else
      {
        const auto ret = json2field(&(itr->value), msg, field);
        if (!ret.empty())
        {
          return ret;
        }
      }
    }
    return "";
  }
}
<commit_msg>todo and retuning on error<commit_after>#include <iostream>
#include "protojson.h"
#include "core/assert.h"
#include "core/str.h"

// todo: add proto-> json
// todo: add error path
// todo: fix naming

namespace
{
  std::string json2field(const rapidjson::Value* json, google::protobuf::Message* msg, const google::protobuf::FieldDescriptor *field)
  {
    const auto* ref = msg->GetReflection();
    const bool repeated = field->is_repeated();
    switch (field->cpp_type())
    {
      case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
      {
        if (json->GetType() != rapidjson::kNumberType)
        {
          return "Not a number";
        }
        if (repeated)
        {
          ref->AddInt32(msg, field, (int32_t) json->GetInt());
        }
        else
        {
          ref->SetInt32(msg, field, (int32_t) json->GetInt());
        }
        break;
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
      {
        if (json->GetType() != rapidjson::kNumberType)
        {
          return "Not a number";
        }
        if (repeated)
        {
          ref->AddUInt32(msg, field, json->GetUint());
        }
        else
        {
          ref->SetUInt32(msg, field, json->GetUint());
        }
        break;
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
      {
        if (json->GetType() != rapidjson::kNumberType)
        {
          return "Not a number";
        }
        if (repeated)
        {
          ref->AddInt64(msg, field, json->GetInt64());
        }
        else
        {
          ref->SetInt64(msg, field, json->GetInt64());
        }
        break;
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
      {
        if (json->GetType() != rapidjson::kNumberType)
        {
          return "Not a number";
        }
        if (repeated)
        {
          ref->AddUInt64(msg, field, json->GetUint64());
        }
        else
        {
          ref->SetUInt64(msg, field, json->GetUint64());
        }
        break;
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
      {
        if (json->GetType() != rapidjson::kNumberType)
        {
          return "Not a number";
        }
        if (repeated)
        {
          ref->AddDouble(msg, field, json->GetDouble());
        }
        else
        {
          ref->SetDouble(msg, field, json->GetDouble());
        }
        break;
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
      {
        if (json->GetType() != rapidjson::kNumberType)
        {
          return "Not a number";
        }
        if (repeated)
        {
          ref->AddFloat(msg, field, json->GetDouble());
        }
        else
        {
          ref->SetFloat(msg, field, json->GetDouble());
        }
        break;
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
      {
        if (json->GetType() != rapidjson::kTrueType && json->GetType() != rapidjson::kFalseType)
        {
          return "Not a bool";
        }
        bool v = json->GetBool();
        if (repeated)
        {
          ref->AddBool(msg, field, v);
        }
        else
        {
          ref->SetBool(msg, field, v);
        }
        break;
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
      {
        if (json->GetType() != rapidjson::kStringType)
        {
          return "Not a string";
        }
        const char* value = json->GetString();
        uint32_t str_size = json->GetStringLength();
        std::string str_value(value, str_size);
        if (field->type() == google::protobuf::FieldDescriptor::TYPE_BYTES)
        {
          if (repeated)
          {
            Assert(false);
            // ref->AddString(msg, field, b64_decode(str_value));
          }
          else
          {
            Assert(false);
            // ref->SetString(msg, field, b64_decode(str_value));
          }
        }
        else
        {
          if (repeated)
          {
            ref->AddString(msg, field, str_value);
          }
          else
          {
            ref->SetString(msg, field, str_value);
          }
        }
        break;
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
      {
        google::protobuf::Message *mf = (repeated) ? ref->AddMessage(msg, field) : ref->MutableMessage(msg, field);
        return protojson::ToProto(*json, mf);
      }
      case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
      {
        const auto* ed = field->enum_type();
        const google::protobuf::EnumValueDescriptor* ev = nullptr;
        if (json->GetType() == rapidjson::kNumberType)
        {
          ev = ed->FindValueByNumber(json->GetInt());
        }
        else if (json->GetType() == rapidjson::kStringType)
        {
          ev = ed->FindValueByName(json->GetString());
        }
        else return "Not an integer or string";
        if (!ev)
          return "Enum value not found";
        if (repeated)
        {
          ref->AddEnum(msg, field, ev);
        }
        else
        {
          ref->SetEnum(msg, field, ev);
        }
        break;
      }
      default:
        break;
    }
    return "";
  }
}

namespace protojson
{
  std::string ToProto(const rapidjson::Value& json, google::protobuf::Message* msg)
  {
    if (json.GetType() != rapidjson::kObjectType)
    {
      return "JSON root is not a object";
    }
    const  auto* d = msg->GetDescriptor();
    const auto* ref = msg->GetReflection();
    if (d == nullptr || ref == nullptr)
    {
      return "Protobuf object has no reflection";
    }

    for (rapidjson::Value::ConstMemberIterator itr = json.MemberBegin(); itr != json.MemberEnd(); ++itr)
    {
      const char* name = itr->name.GetString();
      const auto* field = d->FindFieldByName(name);
      if (field == nullptr)
        field = ref->FindKnownExtensionByName(name);
      if (field == nullptr) {
        return Str() << "Failed to find json field " << name << " in proto";
      }
      if (itr->value.GetType() == rapidjson::kNullType) {
        ref->ClearField(msg, field);
        continue;
      }
      if (field->is_repeated())
      {
        if (itr->value.GetType() != rapidjson::kArrayType) {
          return "Protobuf is repeated but json didnt specify an array";
        }
        for (rapidjson::Value::ConstValueIterator ait = itr->value.Begin(); ait != itr->value.End(); ++ait)
        {
          const auto ret = json2field(ait, msg, field);
          if (!ret.empty())
          {
            return ret;
          }
        }
      }
      else
      {
        const auto ret = json2field(&(itr->value), msg, field);
        if (!ret.empty())
        {
          return ret;
        }
      }
    }
    return "";
  }
}
<|endoftext|>


<commit_before>/*
 * Call.cpp
 *
 * Copyright (C) 2008 by Universitaet Stuttgart (VIS).
 * Alle Rechte vorbehalten.
 */

#include "stdafx.h"
#include "mmcore/RigRendering.h"
#include "mmcore/Call.h"
#include "mmcore/CalleeSlot.h"
#include "mmcore/CallerSlot.h"
#ifdef RIG_RENDERCALLS_WITH_DEBUGGROUPS
#    include "mmcore/view/Renderer2DModule.h"
#    include "mmcore/view/Renderer3DModule.h"
#    include "mmcore/view/Renderer3DModuleGL.h"
#    include "vislib/graphics/gl/IncludeAllGL.h"
#endif
#ifdef PROFILING
#    include "mmcore/view/Renderer3DModuleGL.h"
#    include "mmcore/view/Renderer2DModule.h"
#    include <ctime>
#endif
#include "mmcore/utility/log/Log.h"

using namespace megamol::core;

/*
 * Call::Call
 */
Call::Call(void) : callee(nullptr), caller(nullptr), className(nullptr), funcMap(nullptr) {
    // intentionally empty
}

/*
 * Call::~Call
 */
Call::~Call(void) {
    if (this->caller != nullptr) {
        CallerSlot* cr = this->caller;
        this->caller = nullptr; // DO NOT DELETE
        cr->ConnectCall(nullptr);
    }
    if (this->callee != nullptr) {
        this->callee->ConnectCall(nullptr);
        this->callee = nullptr; // DO NOT DELETE
    }
    megamol::core::utility::log::Log::DefaultLog.WriteMsg(megamol::core::utility::log::Log::LEVEL_INFO + 350, "destructed call \"%s\"\n", typeid(*this).name());
    ARY_SAFE_DELETE(this->funcMap);
}

#ifdef PROFILING
Call::my_query_id::my_query_id() {
    glGenQueries(1, &the_id);
}
Call::my_query_id::~my_query_id() {
    glDeleteQueries(1, &the_id);
}
Call::my_query_id::my_query_id(const my_query_id&) {
    glGenQueries(1, &the_id);
}
#endif

/*
 * Call::operator()
 */
bool Call::operator()(unsigned int func) {
    bool res = false;
    if (this->callee != nullptr) {
#ifdef RIG_RENDERCALLS_WITH_DEBUGGROUPS
        auto f = this->callee->GetCallbackFuncName(func);
        auto parent = callee->Parent().get();
        auto p3 = dynamic_cast<core::view::Renderer3DModule*>(parent);
        auto p3_2 = dynamic_cast<core::view::Renderer3DModuleGL*>(parent);
        auto p2 = dynamic_cast<core::view::Renderer2DModule*>(parent);
        if (p3 || p3_2 || p2) {
            std::string output = dynamic_cast<core::Module*>(parent)->ClassName();
            output += "::";
            output += f;
            glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1234, -1, output.c_str());
            // megamol::core::utility::log::Log::DefaultLog.WriteInfo("called %s::%s", p3->ClassName(), f);
        }
#endif
#ifdef PROFILING
        const auto f = this->callee->GetCallbackFuncName(func);
        const auto parent = this->callee->Parent().get();
        const auto gl_1 = dynamic_cast<core::view::Renderer2DModule*>(parent);
        const auto gl_2 = dynamic_cast<core::view::Renderer3DModuleGL*>(parent);
        const std::clock_t c_start = std::clock();
        const auto paranoid_size = std::max(static_cast<unsigned int>(last_cpu_time.size()), func + 1);
        last_cpu_time.resize(paranoid_size, 0.0);
        avg_cpu_time.resize(paranoid_size, 0.0);
        num_cpu_time_samples.resize(paranoid_size, 0);
        last_gpu_time.resize(paranoid_size, 0.0);
        avg_gpu_time.resize(paranoid_size, 0.0);
        num_gpu_time_samples.resize(paranoid_size, 0);

        if (gl_1 || gl_2) {
            // you can only have one query per target in flight. no idea what to do really.

            //queries[query_start_buffer].resize(paranoid_size);
            //queries[query_read_buffer].resize(paranoid_size);
            //auto& q = queries[query_start_buffer][func];
            //glBeginQuery(GL_TIME_ELAPSED, q.Get());
            //q.Start();
        }
#endif
        res = this->callee->InCall(this->funcMap[func], *this);
#ifdef PROFILING
        const std::clock_t c_end = std::clock();
        last_cpu_time[func] = 1000.0 * (static_cast<double>(c_end-c_start) / CLOCKS_PER_SEC);
        avg_cpu_time[func] = (avg_cpu_time[func] * num_cpu_time_samples[func] + last_cpu_time[func]) / (++num_cpu_time_samples[func]);
        if (gl_1 || gl_2) {
            //GLuint64 time;
            //auto& q = queries[query_read_buffer][func];
            //if (q.Started()) {
            //    int done = 0;
            //    glGetQueryObjectiv(q.Get(), GL_QUERY_RESULT_AVAILABLE, &done);
            //    ASSERT(done);
            //    glGetQueryObjectui64v(q.Get(), GL_QUERY_RESULT, &time);
            //    last_gpu_time[func] = static_cast<double>(time / 1000000.0);
            //    avg_gpu_time[func] = (avg_gpu_time[func] * num_gpu_time_samples[func] + last_gpu_time[func]) / ++num_gpu_time_samples[func];
            //}
            //std::swap(query_start_buffer, query_read_buffer);
        }
#endif
#ifdef RIG_RENDERCALLS_WITH_DEBUGGROUPS
        if (p2 || p3 || p3_2) glPopDebugGroup();
#endif
    }
    // megamol::core::utility::log::Log::DefaultLog.WriteInfo("calling %s, idx %i, result %s (%s)", this->ClassName(), func,
    //    res ? "true" : "false", this->callee == nullptr ? "no callee" : "from callee");
    return res;
}
<commit_msg>operator precedence...<commit_after>/*
 * Call.cpp
 *
 * Copyright (C) 2008 by Universitaet Stuttgart (VIS).
 * Alle Rechte vorbehalten.
 */

#include "stdafx.h"
#include "mmcore/RigRendering.h"
#include "mmcore/Call.h"
#include "mmcore/CalleeSlot.h"
#include "mmcore/CallerSlot.h"
#ifdef RIG_RENDERCALLS_WITH_DEBUGGROUPS
#    include "mmcore/view/Renderer2DModule.h"
#    include "mmcore/view/Renderer3DModule.h"
#    include "mmcore/view/Renderer3DModuleGL.h"
#    include "vislib/graphics/gl/IncludeAllGL.h"
#endif
#ifdef PROFILING
#    include "mmcore/view/Renderer3DModuleGL.h"
#    include "mmcore/view/Renderer2DModule.h"
#    include <ctime>
#endif
#include "mmcore/utility/log/Log.h"

using namespace megamol::core;

/*
 * Call::Call
 */
Call::Call(void) : callee(nullptr), caller(nullptr), className(nullptr), funcMap(nullptr) {
    // intentionally empty
}

/*
 * Call::~Call
 */
Call::~Call(void) {
    if (this->caller != nullptr) {
        CallerSlot* cr = this->caller;
        this->caller = nullptr; // DO NOT DELETE
        cr->ConnectCall(nullptr);
    }
    if (this->callee != nullptr) {
        this->callee->ConnectCall(nullptr);
        this->callee = nullptr; // DO NOT DELETE
    }
    megamol::core::utility::log::Log::DefaultLog.WriteMsg(megamol::core::utility::log::Log::LEVEL_INFO + 350, "destructed call \"%s\"\n", typeid(*this).name());
    ARY_SAFE_DELETE(this->funcMap);
}

#ifdef PROFILING
Call::my_query_id::my_query_id() {
    glGenQueries(1, &the_id);
}
Call::my_query_id::~my_query_id() {
    glDeleteQueries(1, &the_id);
}
Call::my_query_id::my_query_id(const my_query_id&) {
    glGenQueries(1, &the_id);
}
#endif

/*
 * Call::operator()
 */
bool Call::operator()(unsigned int func) {
    bool res = false;
    if (this->callee != nullptr) {
#ifdef RIG_RENDERCALLS_WITH_DEBUGGROUPS
        auto f = this->callee->GetCallbackFuncName(func);
        auto parent = callee->Parent().get();
        auto p3 = dynamic_cast<core::view::Renderer3DModule*>(parent);
        auto p3_2 = dynamic_cast<core::view::Renderer3DModuleGL*>(parent);
        auto p2 = dynamic_cast<core::view::Renderer2DModule*>(parent);
        if (p3 || p3_2 || p2) {
            std::string output = dynamic_cast<core::Module*>(parent)->ClassName();
            output += "::";
            output += f;
            glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1234, -1, output.c_str());
            // megamol::core::utility::log::Log::DefaultLog.WriteInfo("called %s::%s", p3->ClassName(), f);
        }
#endif
#ifdef PROFILING
        const auto f = this->callee->GetCallbackFuncName(func);
        const auto parent = this->callee->Parent().get();
        const auto gl_1 = dynamic_cast<core::view::Renderer2DModule*>(parent);
        const auto gl_2 = dynamic_cast<core::view::Renderer3DModuleGL*>(parent);
        const std::clock_t c_start = std::clock();
        const auto paranoid_size = std::max(static_cast<unsigned int>(last_cpu_time.size()), func + 1);
        last_cpu_time.resize(paranoid_size, 0.0);
        avg_cpu_time.resize(paranoid_size, 0.0);
        num_cpu_time_samples.resize(paranoid_size, 0);
        last_gpu_time.resize(paranoid_size, 0.0);
        avg_gpu_time.resize(paranoid_size, 0.0);
        num_gpu_time_samples.resize(paranoid_size, 0);

        if (gl_1 || gl_2) {
            // you can only have one query per target in flight. no idea what to do really.

            //queries[query_start_buffer].resize(paranoid_size);
            //queries[query_read_buffer].resize(paranoid_size);
            //auto& q = queries[query_start_buffer][func];
            //glBeginQuery(GL_TIME_ELAPSED, q.Get());
            //q.Start();
        }
#endif
        res = this->callee->InCall(this->funcMap[func], *this);
#ifdef PROFILING
        const std::clock_t c_end = std::clock();
        last_cpu_time[func] = 1000.0 * (static_cast<double>(c_end-c_start) / CLOCKS_PER_SEC);
        const auto total = (avg_cpu_time[func] * num_cpu_time_samples[func] + last_cpu_time[func]);
        num_cpu_time_samples[func]++;
        avg_cpu_time[func] = total / static_cast<double>(num_cpu_time_samples[func]);
        if (gl_1 || gl_2) {
            //GLuint64 time;
            //auto& q = queries[query_read_buffer][func];
            //if (q.Started()) {
            //    int done = 0;
            //    glGetQueryObjectiv(q.Get(), GL_QUERY_RESULT_AVAILABLE, &done);
            //    ASSERT(done);
            //    glGetQueryObjectui64v(q.Get(), GL_QUERY_RESULT, &time);
            //    last_gpu_time[func] = static_cast<double>(time / 1000000.0);
            //    avg_gpu_time[func] = (avg_gpu_time[func] * num_gpu_time_samples[func] + last_gpu_time[func]) / ++num_gpu_time_samples[func];
            //}
            //std::swap(query_start_buffer, query_read_buffer);
        }
#endif
#ifdef RIG_RENDERCALLS_WITH_DEBUGGROUPS
        if (p2 || p3 || p3_2) glPopDebugGroup();
#endif
    }
    // megamol::core::utility::log::Log::DefaultLog.WriteInfo("calling %s, idx %i, result %s (%s)", this->ClassName(), func,
    //    res ? "true" : "false", this->callee == nullptr ? "no callee" : "from callee");
    return res;
}
<|endoftext|>


<commit_before>#include "options.h"
#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <string>

program_options options = { false,false,false,false,false,8 };

bool get_options(int argc, char* argv[]){
  int c;
  opterr = 0;
  while ((c = getopt (argc, argv, "adfhl:v")) != -1){
    switch (c){
      case 'a':
        options.include_hidden = true;
        break;
      case 'd':
        options.directories_only = true;
        break;
      case 'f':
        options.files_only = true;
        break;
      case 'h':
        options.show_help = true;
        break;
      case 'l':
        options.number_of_result_lines = std::atoi(optarg);
        break;
      case 'v':
        options.show_version = true;
        break;
      case '?':
        if (optopt == 'l')
          fprintf (stderr, "Option -%c requires an argument.\n", optopt);
        else if (isprint (optopt))
          fprintf (stderr, "Unknown option '-%c'.\n", optopt);
        else
          fprintf (stderr,
                   "Unknown option character '\\x%x'.\n",
                   optopt);
        return false;
      default:
        abort ();
      }
  }
  return true;
}

void print_version(){
  printf("search version %s\n",SEARCHVERSION);
}

void print_help(){
  printf("Usage: search [OPTION]... [PATH]\n");
  printf("\n");
  printf("Options:\n");
  printf("  -h    show this help message and exit.\n");
  printf("  -v    show version info and exit.\n");
  printf("  -a     do not ignore entries starting with '.'.\n");
  printf("  -l L  use L number of lines to show result.\n");
  printf("  -f    search only for files. ignore directories.\n");
  printf("  -d    search only for directories. ignore files.\n");
}
<commit_msg>Remove space in string.<commit_after>#include "options.h"
#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <string>

program_options options = { false,false,false,false,false,8 };

bool get_options(int argc, char* argv[]){
  int c;
  opterr = 0;
  while ((c = getopt (argc, argv, "adfhl:v")) != -1){
    switch (c){
      case 'a':
        options.include_hidden = true;
        break;
      case 'd':
        options.directories_only = true;
        break;
      case 'f':
        options.files_only = true;
        break;
      case 'h':
        options.show_help = true;
        break;
      case 'l':
        options.number_of_result_lines = std::atoi(optarg);
        break;
      case 'v':
        options.show_version = true;
        break;
      case '?':
        if (optopt == 'l')
          fprintf (stderr, "Option -%c requires an argument.\n", optopt);
        else if (isprint (optopt))
          fprintf (stderr, "Unknown option '-%c'.\n", optopt);
        else
          fprintf (stderr,
                   "Unknown option character '\\x%x'.\n",
                   optopt);
        return false;
      default:
        abort ();
      }
  }
  return true;
}

void print_version(){
  printf("search version %s\n",SEARCHVERSION);
}

void print_help(){
  printf("Usage: search [OPTION]... [PATH]\n");
  printf("\n");
  printf("Options:\n");
  printf("  -h    show this help message and exit.\n");
  printf("  -v    show version info and exit.\n");
  printf("  -a    do not ignore entries starting with '.'.\n");
  printf("  -l L  use L number of lines to show result.\n");
  printf("  -f    search only for files. ignore directories.\n");
  printf("  -d    search only for directories. ignore files.\n");
}
<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/CopasiSE/CopasiSE.cpp,v $
   $Revision: 1.24 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/11/30 13:35:43 $
   End CVS Header */

// Main
//
// (C) Stefan Hoops 2002
//

#include <stdlib.h>
#include <sstream>
#include <string>
#include <iostream>

#define COPASI_MAIN

#include "copasi.h"
#include "CopasiDataModel/CCopasiDataModel.h"
#include "utilities/CCopasiMessage.h"
#include "utilities/CCopasiException.h"
#include "utilities/CCopasiTask.h"
#include "utilities/CCopasiProblem.h"
#include "commandline/COptionParser.h"
#include "commandline/COptions.h"
#include "function/CFunctionDB.h"
#include "function/CEvaluationTree.h"
#include "function/CFunction.h"

#include "randomGenerator/CRandom.h"
#include "report/CCopasiTimer.h"
#include "report/CKeyFactory.h"
#include "utilities/CVersion.h"
#include "utilities/CDirEntry.h"

int main(int argc, char *argv[])
{
  std::stringstream Out;
  std::stringstream Error;

  try
    {
      // Parse the commandline options
      COptions::init(argc, argv);
    }

  catch (copasi::autoexcept &e)
    {
      switch (e.get_autothrow_id())
        {
        case copasi::autothrow_help:
          Out << "Usage: " << CDirEntry::baseName(argv[0]) << " [options] [file]\n";
          Out << e.what();
        }
    }

  catch (copasi::option_error &e)
    {
      Error << CDirEntry::baseName(argv[0]) << ": " << e.what() << "\n";
      Error << e.get_help_comment() << std::endl;
    }

  try
    {
      // Create the root container.
      CCopasiContainer::init();

      // Create the global data model.
      CCopasiDataModel::Global = new CCopasiDataModel;

      std::cout << "COPASI Version "
      << CCopasiDataModel::Global->getVersion()->getVersion()
      << std::endl << std::endl;

      if (Out.str() != "")
        {
          std::cout << Out.str();
          return 1;
        }

      if (Error.str() != "")
        {
          std::cerr << Error.str();
          return 1;
        }

#ifdef XXXX
      CCallParameters<C_FLOAT64> Variables(20);
      unsigned C_INT32 j, i, imax = Variables.size();
      CRandom * pRandom = CRandom::createGenerator();

      for (i = 0; i < imax; i++)
        {
          C_FLOAT64 * pValue = new C_FLOAT64;
          *pValue = 100.0 * pRandom->getRandomOO();
          Variables[i].value = pValue;
        }

      CCopasiTimer * pCPU =
        const_cast<CCopasiTimer *>(static_cast<const CCopasiTimer *>(CCopasiContainer::Root->getObject((std::string)"CN=Root,Timer=CPU Time")));
      CCopasiTimer * pWall =
        const_cast<CCopasiTimer *>(static_cast<const CCopasiTimer *>(CCopasiContainer::Root->getObject((std::string)"CN=Root,Timer=Wall Clock Time")));

      CCopasiVectorN< CEvaluationTree > & Functions =
        CCopasiDataModel::Global->getFunctionList()->loadedFunctions();
      CFunction * pFunction;

      for (i = 0, imax = Functions.size(); i < imax; i++)
        {
          pFunction = dynamic_cast<CFunction *>(Functions[i]);
          if (pFunction->getType() != CEvaluationTree::MassAction)
            for (j = 0; j < 100000; j++)
              pFunction->calcValue(Variables);
        }

      pCPU->actualize();
      pWall->actualize();

      std::cout << "CPU time:  ";
      pCPU->print(&std::cout);
      std::cout << std::endl;

      std::cout << "Wall time: ";
      pWall->print(&std::cout);
      std::cout << std::endl;
#endif // XXXX

#ifdef XXXX
      CEvaluationTree Expression;
      Expression.setInfix("5**-sin(x)");
      Expression.setInfix("a*5.0/-b");
      Expression.setInfix("EXPONENTIALE+b*c");
      Expression.setInfix("4.0*\"PI+b");
      Expression.setInfix("2*(3+b)");
#endif

      const COptions::nonOptionType & Files = COptions::getNonOptions();

      if (!COptions::compareValue("ImportSBML", std::string("")))
        {
          // Import the SBML File
          std::string ImportSBML;
          COptions::getValue("ImportSBML", ImportSBML);
          CCopasiDataModel::Global->importSBML(ImportSBML);

          // Check whether exporting to SBML is requested.
          if (!COptions::compareValue("ExportSBML", std::string("")))
            {
              // Export the SBML File
              std::string ExportSBML;
              COptions::getValue("ExportSBML", ExportSBML);
              CCopasiDataModel::Global->exportSBML(ExportSBML, true);
            }

          // Check whether a save file is given.
          if (!COptions::compareValue("Save", std::string("")))
            {
              std::string Save;
              COptions::getValue("Save", Save);

              CCopasiDataModel::Global->saveModel(Save, true);
            }

          // If no export or save file was given, we write to the
          // default file, but do not overwrite any existing file.
          if (COptions::compareValue("ExportSBML", std::string("")) &&
              COptions::compareValue("Save", std::string("")))
            CCopasiDataModel::Global->saveModel("", false);
        }
      else
        {
          COptions::nonOptionType::const_iterator it = Files.begin();
          COptions::nonOptionType::const_iterator end = Files.end();

          if (it == end) // Create a usage message
            {
              std::string Help = "--help";
              const char * Argv[2];
              Argv[0] = argv[0];
              Argv[1] = Help.c_str();

              copasi::COptionParser * pParser = new copasi::COptionParser;
              try
                {
                  pParser->parse(2, (char **) Argv);
                }

              catch (copasi::autoexcept &e)
                {
                  switch (e.get_autothrow_id())
                    {
                    case copasi::autothrow_help:
                      std::cout << "Usage: " << CDirEntry::baseName(argv[0]) << " [options] [file]\n";
                      std::cout << e.what();
                    }
                }

              return 1;
            }

          for (; it != end; ++it)
            {
              CCopasiDataModel::Global->loadModel(*it);

              // Check whether exporting to SBML is requested.
              if (!COptions::compareValue("ExportSBML", std::string("")))
                {
                  // Export the SBML File
                  std::string ExportSBML;
                  COptions::getValue("ExportSBML", ExportSBML);
                  CCopasiDataModel::Global->exportSBML(ExportSBML, true);

                  // Since only one export file name can be specified we
                  // stop execution.
                  break;
                }

              CCopasiVectorN< CCopasiTask > & TaskList = * CCopasiDataModel::Global->getTaskList();
              unsigned C_INT32 i, imax = TaskList.size();

              for (i = 0; i < imax; i++)
                if (TaskList[i]->isScheduled())
                  {
                    TaskList[i]->getProblem()->setModel(CCopasiDataModel::Global->getModel());

                    TaskList[i]->initialize(CCopasiTask::OUTPUT_COMPLETE, NULL);
                    TaskList[i]->process(true);
                    TaskList[i]->restore();
                  }

              // Check whether a file for saving the resulting model is given
              if (!COptions::compareValue("Save", std::string("")))
                {
                  std::string Save;
                  COptions::getValue("Save", Save);
                  CCopasiDataModel::Global->saveModel(Save, true);

                  // Since only one save file name can be specified we
                  // stop execution.
                  break;
                }
            }
        }
    }

  catch (CCopasiException Exception)
    {
      std::cout << Exception.getMessage().getText() << std::endl;
    }

  pdelete(CCopasiDataModel::Global);
  pdelete(CCopasiContainer::Root);

  //std::cout << "Leaving main program." << std::endl;
  return 0;
}
<commit_msg>Implemented performance test for sparse matrices (not executed).<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/CopasiSE/CopasiSE.cpp,v $
   $Revision: 1.25 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/12/12 20:20:38 $
   End CVS Header */

// Main
//
// (C) Stefan Hoops 2002
//

#include <stdlib.h>
#include <sstream>
#include <string>
#include <iostream>

#define COPASI_MAIN

#include "copasi.h"
#include "CopasiDataModel/CCopasiDataModel.h"
#include "utilities/CCopasiMessage.h"
#include "utilities/CCopasiException.h"
#include "utilities/CCopasiTask.h"
#include "utilities/CCopasiProblem.h"
#include "commandline/COptionParser.h"
#include "commandline/COptions.h"
#include "function/CFunctionDB.h"
#include "function/CEvaluationTree.h"
#include "function/CFunction.h"

#include "randomGenerator/CRandom.h"
#include "report/CCopasiTimer.h"
#include "report/CKeyFactory.h"
#include "utilities/CVersion.h"
#include "utilities/CDirEntry.h"
#include "utilities/CSparseMatrix.h"

int main(int argc, char *argv[])
{
  std::stringstream Out;
  std::stringstream Error;

#ifdef XXXX
  C_FLOAT64 sparseness = 0.00;
  SparseMatrixTest(10, sparseness);
  SparseMatrixTest(25, sparseness);
  SparseMatrixTest(50, sparseness);
  SparseMatrixTest(100, sparseness);
  SparseMatrixTest(250, sparseness);
  SparseMatrixTest(500, sparseness);
  SparseMatrixTest(1000, sparseness);

  return 0;
#endif XXXX

  try
    {
      // Parse the commandline options
      COptions::init(argc, argv);
    }

  catch (copasi::autoexcept &e)
    {
      switch (e.get_autothrow_id())
        {
        case copasi::autothrow_help:
          Out << "Usage: " << CDirEntry::baseName(argv[0]) << " [options] [file]\n";
          Out << e.what();
        }
    }

  catch (copasi::option_error &e)
    {
      Error << CDirEntry::baseName(argv[0]) << ": " << e.what() << "\n";
      Error << e.get_help_comment() << std::endl;
    }

  try
    {
      // Create the root container.
      CCopasiContainer::init();

      // Create the global data model.
      CCopasiDataModel::Global = new CCopasiDataModel;

      std::cout << "COPASI Version "
      << CCopasiDataModel::Global->getVersion()->getVersion()
      << std::endl << std::endl;

      if (Out.str() != "")
        {
          std::cout << Out.str();
          return 1;
        }

      if (Error.str() != "")
        {
          std::cerr << Error.str();
          return 1;
        }

#ifdef XXXX
      CCallParameters<C_FLOAT64> Variables(20);
      unsigned C_INT32 j, i, imax = Variables.size();
      CRandom * pRandom = CRandom::createGenerator();

      for (i = 0; i < imax; i++)
        {
          C_FLOAT64 * pValue = new C_FLOAT64;
          *pValue = 100.0 * pRandom->getRandomOO();
          Variables[i].value = pValue;
        }

      CCopasiTimer * pCPU =
        const_cast<CCopasiTimer *>(static_cast<const CCopasiTimer *>(CCopasiContainer::Root->getObject((std::string)"CN=Root,Timer=CPU Time")));
      CCopasiTimer * pWall =
        const_cast<CCopasiTimer *>(static_cast<const CCopasiTimer *>(CCopasiContainer::Root->getObject((std::string)"CN=Root,Timer=Wall Clock Time")));

      CCopasiVectorN< CEvaluationTree > & Functions =
        CCopasiDataModel::Global->getFunctionList()->loadedFunctions();
      CFunction * pFunction;

      for (i = 0, imax = Functions.size(); i < imax; i++)
        {
          pFunction = dynamic_cast<CFunction *>(Functions[i]);
          if (pFunction->getType() != CEvaluationTree::MassAction)
            for (j = 0; j < 100000; j++)
              pFunction->calcValue(Variables);
        }

      pCPU->actualize();
      pWall->actualize();

      std::cout << "CPU time:  ";
      pCPU->print(&std::cout);
      std::cout << std::endl;

      std::cout << "Wall time: ";
      pWall->print(&std::cout);
      std::cout << std::endl;
#endif // XXXX

#ifdef XXXX
      CEvaluationTree Expression;
      Expression.setInfix("5**-sin(x)");
      Expression.setInfix("a*5.0/-b");
      Expression.setInfix("EXPONENTIALE+b*c");
      Expression.setInfix("4.0*\"PI+b");
      Expression.setInfix("2*(3+b)");
#endif

      const COptions::nonOptionType & Files = COptions::getNonOptions();

      if (!COptions::compareValue("ImportSBML", std::string("")))
        {
          // Import the SBML File
          std::string ImportSBML;
          COptions::getValue("ImportSBML", ImportSBML);
          CCopasiDataModel::Global->importSBML(ImportSBML);

          // Check whether exporting to SBML is requested.
          if (!COptions::compareValue("ExportSBML", std::string("")))
            {
              // Export the SBML File
              std::string ExportSBML;
              COptions::getValue("ExportSBML", ExportSBML);
              CCopasiDataModel::Global->exportSBML(ExportSBML, true);
            }

          // Check whether a save file is given.
          if (!COptions::compareValue("Save", std::string("")))
            {
              std::string Save;
              COptions::getValue("Save", Save);

              CCopasiDataModel::Global->saveModel(Save, true);
            }

          // If no export or save file was given, we write to the
          // default file, but do not overwrite any existing file.
          if (COptions::compareValue("ExportSBML", std::string("")) &&
              COptions::compareValue("Save", std::string("")))
            CCopasiDataModel::Global->saveModel("", false);
        }
      else
        {
          COptions::nonOptionType::const_iterator it = Files.begin();
          COptions::nonOptionType::const_iterator end = Files.end();

          if (it == end) // Create a usage message
            {
              std::string Help = "--help";
              const char * Argv[2];
              Argv[0] = argv[0];
              Argv[1] = Help.c_str();

              copasi::COptionParser * pParser = new copasi::COptionParser;
              try
                {
                  pParser->parse(2, (char **) Argv);
                }

              catch (copasi::autoexcept &e)
                {
                  switch (e.get_autothrow_id())
                    {
                    case copasi::autothrow_help:
                      std::cout << "Usage: " << CDirEntry::baseName(argv[0]) << " [options] [file]\n";
                      std::cout << e.what();
                    }
                }

              return 1;
            }

          for (; it != end; ++it)
            {
              CCopasiDataModel::Global->loadModel(*it);

              // Check whether exporting to SBML is requested.
              if (!COptions::compareValue("ExportSBML", std::string("")))
                {
                  // Export the SBML File
                  std::string ExportSBML;
                  COptions::getValue("ExportSBML", ExportSBML);
                  CCopasiDataModel::Global->exportSBML(ExportSBML, true);

                  // Since only one export file name can be specified we
                  // stop execution.
                  break;
                }

              CCopasiVectorN< CCopasiTask > & TaskList = * CCopasiDataModel::Global->getTaskList();
              unsigned C_INT32 i, imax = TaskList.size();

              for (i = 0; i < imax; i++)
                if (TaskList[i]->isScheduled())
                  {
                    TaskList[i]->getProblem()->setModel(CCopasiDataModel::Global->getModel());

                    TaskList[i]->initialize(CCopasiTask::OUTPUT_COMPLETE, NULL);
                    TaskList[i]->process(true);
                    TaskList[i]->restore();
                  }

              // Check whether a file for saving the resulting model is given
              if (!COptions::compareValue("Save", std::string("")))
                {
                  std::string Save;
                  COptions::getValue("Save", Save);
                  CCopasiDataModel::Global->saveModel(Save, true);

                  // Since only one save file name can be specified we
                  // stop execution.
                  break;
                }
            }
        }
    }

  catch (CCopasiException Exception)
    {
      std::cout << Exception.getMessage().getText() << std::endl;
    }

  pdelete(CCopasiDataModel::Global);
  pdelete(CCopasiContainer::Root);

  //std::cout << "Leaving main program." << std::endl;
  return 0;
}
<|endoftext|>


<commit_before>#include "fmd.h"

namespace CSA
{

FMDPosition::FMDPosition(usint forward_start, usint reverse_start, usint length):
  forward_start(forward_start), reverse_start(reverse_start), length(length)
{
}

FMDPosition::FMDPosition(): forward_start(0), reverse_start(0), length(0)
{
}

std::ostream& operator<< (std::ostream& o, FMDPosition const& position)
{
  // Report both the ranges that we represent.
  return o << position.forward_start << "-" <<
    (position.forward_start + position.length) << "|" <<
    position.reverse_start << "-" << (position.reverse_start + position.length);
}

FMD::FMD(const std::string& base_name, bool print):
  RLCSA(base_name, print)
{
}

FMDPosition
FMD::extend(FMDPosition range, usint c, bool backward) const
{

  // More or less directly implemented off of algorithms 2 and 3 in "Exploring
  // single-sample SNP and INDEL calling with whole-genome de novo assembly"
  // (Li, 2012). However, our character indices are one less, since we don't
  // allow search patterns to include the end-of-text symbol.

  if(backward)
  {

    // Only allow characters in the index
    if(c >= CHARS || this->array[c] == 0) { return EMPTY_FMD_POSITION; }
    // Only allow DNA bases
    if(!isBase(c)) { return EMPTY_FMD_POSITION; }

    std::cout << "Extending backwards with " << (char)c << std::endl;

    // We have an array of FMDPositions, one per base, that we will fill in by a
    // tiny dynamic programming.
    FMDPosition answers[NUM_BASES];

    // Since we don't keep an FMDPosition for the non-base end-of-text
    // character, we need to track its length separately in order for the DP
    // algorithm given in the paper to be implementable. We calculate
    // occurrences of the text end character analytically, since we know there
    // are this->number_of_sequences of them, at the start of the BWT space.
    usint endOfTextLength = std::min((range.forward_start + range.length - 1),
      this->number_of_sequences) - std::min(this->number_of_sequences,
      (range.forward_start - 1));

    std::cout << "\tendOfTextLength = " << endOfTextLength << std::endl;

    for(usint base = 0; base < NUM_BASES; base++)
    {

      std::cout << "\tThinking about base " << base << "(" << BASES[base] << ")" << std::endl;

      // Count up the number of characters < this base, including sequence stop
      // characters.
      usint start = this->alphabet->cumulative((usint)BASES[base]) +
        this->number_of_sequences - 1;

      std::cout << "\t\tstart = " << start << std::endl;

      // Get a pointer to the bit vector for this letter, which might be NULL if
      // this base never appeared.
      PsiVector* vector = this->array[(usint)BASES[base]];

      if(vector == NULL)
      {
        std::cout << "\t\tCharacter never appeared!" << std::endl;

        // Fill in forward_start and length with the knowledge that this
        // character doesn't exist. forward_start should never get used, but
        // length will get used and probably needs to be 0.
        answers[base].length = 0;

      }
      else
      {
        std::cout << "\t\tCharacter appeared." << std::endl;

        // Get an iterator for the bit vector for this character, for
        // calculating ranks/occurrences.
        PsiVector::Iterator iter(*vector);

        std::cout << "\t\tGot iterator" << std::endl;

        // Fill in the forward-strand start positions and range lengths for each
        // base's answer. TODO: do we want at_least set or not? What does it do?
        answers[base].forward_start = start + iter.rank(range.forward_start,
          true);
        answers[base].length = iter.rank(range.forward_start + range.length,
          true) - iter.rank(range.forward_start, true);

      }

      std::cout << "\t\tWould go to: " << answers[base].forward_start << "-" << answers[base].forward_start + answers[base].length << std::endl;
    }

    // Set up the dynamic programming for the reverse start, to figure out where
    // the corresponding reverse intervals are.
    answers[3].reverse_start = range.reverse_start + endOfTextLength;

    std::cout << "\t" << BASES[3] << " reverse_start is " << answers[3].reverse_start << std::endl;

    for(int base = 2; base >= 0; base--)
    {
      answers[base].reverse_start = answers[base + 1].reverse_start +
        answers[base + 1].length;

      std::cout << "\t" << BASES[base] << " reverse_start is " << answers[base].reverse_start << std::endl;
    }

    // N comes after (before?) everything for some reason. TODO: why? Is it
    // something to do with the encoding Heng uses?
    answers[4].reverse_start = answers[0].reverse_start + answers[0].length;

    std::cout << "\t" << BASES[4] << " reverse_start is " << answers[4].reverse_start << std::endl;

    // Return the correct answer for the base we actually want
    for(usint base = 0; base < NUM_BASES; base++)
    {
      if(BASES[base] == (char)c)
      {
        std::cout << "Moving to " << answers[base] << " on " << BASES[base] << std::endl;
        // We found the right index for this character. Return that answer
        return answers[base];
      }
    }

    // If we ger here, they gave us something not in BASES somehow.
    throw "Unrecognized base";
  }
  else
  {

    // Flip the input interval. TODO: why does GCC think these things may have
    // uninitialized members?
    FMDPosition reverse(range.reverse_start, range.forward_start, range.length);

    // Do backwards search with the reverse complement of the base
    FMDPosition extended = this->extend(reverse, reverse_complement(c),
      true);

    // Reverse the interval again
    FMDPosition forward(extended.reverse_start, extended.reverse_start,
      extended.length);
    return forward;

  }
}

FMDPosition
FMD::getSAPosition() const
{
  return FMDPosition(0, 0, this->data_size - 1);
}

FMDPosition
FMD::fmdCount(const std::string& pattern) const
{
  std::cout << "Counting " << pattern << std::endl;

  if(pattern.length() == 0) { return this->getSAPosition(); }

  std::string::const_reverse_iterator iter = pattern.rbegin();
  FMDPosition index_position = this->getCharPosition((uchar)*iter);
  if(index_position.length <= 0) { return index_position; }

  std::cout << "Starting with " << index_position << std::endl;

  for(++iter; iter != pattern.rend(); ++iter)
  {
    // Backwards extend with subsequent characters.
    index_position = this->extend(index_position, *iter, true);
    std::cout << "Now at " << index_position << " after " << *iter << std::endl;
    if(index_position.length <= 0) { return EMPTY_FMD_POSITION; }
  }
  this->convertToSAPosition(index_position);

  return index_position;
}

FMDPosition
FMD::getCharPosition(usint c) const
{
  if(c >= CHARS || this->array[c] == 0) { return EMPTY_FMD_POSITION; }
  if(!isBase(c)) { return EMPTY_FMD_POSITION; }

  pair_type forward_range = this->alphabet->getRange(c);
  this->convertToBWTRange(forward_range);
  std::cout << (char)c << " range: " << forward_range.first << "-" << forward_range.second << std::endl;

  pair_type reverse_range = this->alphabet->getRange(reverse_complement(c));
  this->convertToBWTRange(reverse_range);
  std::cout << (char)reverse_complement(c) << " range: " << reverse_range.first << "-" << reverse_range.second << std::endl;

  // Make the FMDPosition rolling together both ranges.
  // TODO: Make sure both ranges are the same length, as they should be.
  FMDPosition position(forward_range.first, reverse_range.first,
    forward_range.second - forward_range.first);

  return position;
}

void
FMD::convertToSAPosition(FMDPosition& bwt_position) const
{
  bwt_position.forward_start -= this->number_of_sequences;
  bwt_position.reverse_start -= this->number_of_sequences;
}

}
<commit_msg>State transitions during FMD (backwards) search appear reversible<commit_after>#include "fmd.h"

namespace CSA
{

FMDPosition::FMDPosition(usint forward_start, usint reverse_start, usint length):
  forward_start(forward_start), reverse_start(reverse_start), length(length)
{
}

FMDPosition::FMDPosition(): forward_start(0), reverse_start(0), length(0)
{
}

std::ostream& operator<< (std::ostream& o, FMDPosition const& position)
{
  // Report both the ranges that we represent.
  return o << position.forward_start << "-" <<
    (position.forward_start + position.length) << "|" <<
    position.reverse_start << "-" << (position.reverse_start + position.length);
}

FMD::FMD(const std::string& base_name, bool print):
  RLCSA(base_name, print)
{
}

FMDPosition
FMD::extend(FMDPosition range, usint c, bool backward) const
{

  // More or less directly implemented off of algorithms 2 and 3 in "Exploring
  // single-sample SNP and INDEL calling with whole-genome de novo assembly"
  // (Li, 2012). However, our character indices are one less, since we don't
  // allow search patterns to include the end-of-text symbol.

  if(backward)
  {

    // Only allow characters in the index
    if(c >= CHARS || this->array[c] == 0) { return EMPTY_FMD_POSITION; }
    // Only allow DNA bases
    if(!isBase(c)) { return EMPTY_FMD_POSITION; }

    std::cout << "Extending backwards with " << (char)c << std::endl;

    // We have an array of FMDPositions, one per base, that we will fill in by a
    // tiny dynamic programming.
    FMDPosition answers[NUM_BASES];

    // Since we don't keep an FMDPosition for the non-base end-of-text
    // character, we need to track its length separately in order for the DP
    // algorithm given in the paper to be implementable. We calculate
    // occurrences of the text end character analytically, since we know there
    // are this->number_of_sequences of them, at the start of the BWT space.
    usint endOfTextLength = std::min((range.forward_start + range.length - 1),
      this->number_of_sequences) - std::min(this->number_of_sequences,
      (range.forward_start - 1));

    std::cout << "\tendOfTextLength = " << endOfTextLength << std::endl;

    for(usint base = 0; base < NUM_BASES; base++)
    {

      std::cout << "\tThinking about base " << base << "(" << BASES[base] << ")" << std::endl;

      // Count up the number of characters < this base, including sequence stop
      // characters.
      usint start = this->alphabet->cumulative((usint)BASES[base]) +
        this->number_of_sequences - 1;

      std::cout << "\t\tstart = " << start << std::endl;

      // Get a pointer to the bit vector for this letter, which might be NULL if
      // this base never appeared.
      PsiVector* vector = this->array[(usint)BASES[base]];

      if(vector == NULL)
      {
        std::cout << "\t\tCharacter never appeared!" << std::endl;

        // Fill in forward_start and length with the knowledge that this
        // character doesn't exist. forward_start should never get used, but
        // length will get used and probably needs to be 0.
        answers[base].length = 0;

      }
      else
      {
        std::cout << "\t\tCharacter appeared." << std::endl;

        // Get an iterator for the bit vector for this character, for
        // calculating ranks/occurrences.
        PsiVector::Iterator iter(*vector);

        std::cout << "\t\tGot iterator" << std::endl;

        // Fill in the forward-strand start positions and range lengths for each
        // base's answer. TODO: do we want at_least set or not? What does it do?
        answers[base].forward_start = start + iter.rank(range.forward_start,
          true);
        answers[base].length = iter.rank(range.forward_start + range.length,
          true) - iter.rank(range.forward_start, true);

      }

      std::cout << "\t\tWould go to: " << answers[base].forward_start << "-" << answers[base].forward_start + answers[base].length << std::endl;
    }

    // Set up the dynamic programming for the reverse start, to figure out where
    // the corresponding reverse intervals are.
    answers[3].reverse_start = range.reverse_start + endOfTextLength;

    std::cout << "\t" << BASES[3] << " reverse_start is " << answers[3].reverse_start << std::endl;

    for(int base = 2; base >= 0; base--)
    {
      answers[base].reverse_start = answers[base + 1].reverse_start +
        answers[base + 1].length;

      std::cout << "\t" << BASES[base] << " reverse_start is " << answers[base].reverse_start << std::endl;
    }

    // N comes after (before?) everything for some reason. TODO: why? Is it
    // something to do with the encoding Heng uses?
    answers[4].reverse_start = answers[0].reverse_start + answers[0].length;

    std::cout << "\t" << BASES[4] << " reverse_start is " << answers[4].reverse_start << std::endl;

    // Return the correct answer for the base we actually want
    for(usint base = 0; base < NUM_BASES; base++)
    {
      if(BASES[base] == (char)c)
      {
        std::cout << "Moving " << range << " to " << answers[base] << " on " << BASES[base] << std::endl;
        // We found the right index for this character. Return that answer
        return answers[base];
      }
    }

    // If we ger here, they gave us something not in BASES somehow.
    throw "Unrecognized base";
  }
  else
  {

    // Flip the input interval. TODO: why does GCC think these things may have
    // uninitialized members?
    FMDPosition reverse(range.reverse_start, range.forward_start, range.length);

    // Do backwards search with the reverse complement of the base
    FMDPosition extended = this->extend(reverse, reverse_complement(c),
      true);

    // Reverse the interval again
    FMDPosition forward(extended.reverse_start, extended.reverse_start,
      extended.length);
    return forward;

  }
}

FMDPosition
FMD::getSAPosition() const
{
  return FMDPosition(0, 0, this->data_size - 1);
}

FMDPosition
FMD::fmdCount(const std::string& pattern) const
{
  std::cout << "Counting " << pattern << std::endl;

  if(pattern.length() == 0) { return this->getSAPosition(); }

  std::string::const_reverse_iterator iter = pattern.rbegin();
  FMDPosition index_position = this->getCharPosition((uchar)*iter);
  if(index_position.length <= 0) { return index_position; }

  std::cout << "Starting with " << index_position << std::endl;

  for(++iter; iter != pattern.rend(); ++iter)
  {
    // Backwards extend with subsequent characters.
    index_position = this->extend(index_position, *iter, true);
    std::cout << "Now at " << index_position << " after " << *iter << std::endl;
    if(index_position.length <= 0) { return EMPTY_FMD_POSITION; }
  }
  this->convertToSAPosition(index_position);

  return index_position;
}

FMDPosition
FMD::getCharPosition(usint c) const
{
  if(c >= CHARS || this->array[c] == 0) { return EMPTY_FMD_POSITION; }
  if(!isBase(c)) { return EMPTY_FMD_POSITION; }

  pair_type forward_range = this->alphabet->getRange(c);
  this->convertToBWTRange(forward_range);
  std::cout << (char)c << " range: " << forward_range.first << "-" << forward_range.second << std::endl;

  pair_type reverse_range = this->alphabet->getRange(reverse_complement(c));
  this->convertToBWTRange(reverse_range);
  std::cout << (char)reverse_complement(c) << " range: " << reverse_range.first << "-" << reverse_range.second << std::endl;

  // Make the FMDPosition rolling together both ranges.
  // TODO: Make sure both ranges are the same length, as they should be.
  FMDPosition position(forward_range.first, reverse_range.first,
    forward_range.second - forward_range.first);

  return position;
}

void
FMD::convertToSAPosition(FMDPosition& bwt_position) const
{
  bwt_position.forward_start -= this->number_of_sequences;
  bwt_position.reverse_start -= this->number_of_sequences;
}

}
<|endoftext|>