コード例 #1
0
ファイル: assembly_graph_store.c プロジェクト: huyba/biosal
struct biosal_assembly_vertex *biosal_assembly_graph_store_find_vertex(struct thorium_actor *self,
                struct biosal_dna_kmer *kmer)
{
    struct core_memory_pool *ephemeral_memory;
    struct biosal_assembly_graph_store *concrete_self;
    char *sequence;
    struct biosal_dna_kmer storage_kmer;
    char *key;
    struct biosal_assembly_vertex *canonical_vertex;

    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);
    concrete_self = thorium_actor_concrete_actor(self);

    sequence = core_memory_pool_allocate(ephemeral_memory, concrete_self->kmer_length + 1);

    biosal_dna_kmer_get_sequence(kmer, sequence, concrete_self->kmer_length,
                        &concrete_self->transport_codec);

    biosal_dna_kmer_init(&storage_kmer, sequence, &concrete_self->storage_codec,
                        ephemeral_memory);

    key = core_memory_pool_allocate(ephemeral_memory, concrete_self->key_length_in_bytes);

    biosal_dna_kmer_pack_store_key(&storage_kmer, key,
                        concrete_self->kmer_length, &concrete_self->storage_codec,
                        ephemeral_memory);

    canonical_vertex = core_map_get(&concrete_self->table, key);

#ifdef CORE_DEBUGGER_ASSERT
    if (canonical_vertex == NULL) {

        printf("not found Seq = %s name %d kmerlength %d key_length %d hash %" PRIu64 "\n", sequence,
                        thorium_actor_name(self),
                        concrete_self->kmer_length,
                        concrete_self->key_length_in_bytes,
                        biosal_dna_kmer_hash(&storage_kmer, concrete_self->kmer_length,
                                &concrete_self->storage_codec));
    }
#endif

    CORE_DEBUGGER_ASSERT(canonical_vertex != NULL);

    core_memory_pool_free(ephemeral_memory, sequence);
    core_memory_pool_free(ephemeral_memory, key);
    biosal_dna_kmer_destroy(&storage_kmer, ephemeral_memory);

    return canonical_vertex;
}
コード例 #2
0
ファイル: proxy_message.c プロジェクト: levinas/biosal
void thorium_actor_pack_proxy_message(struct thorium_actor *self, struct thorium_message *message,
                int real_source)
{
    int real_tag;
    int count;
    int new_count;
    void *buffer;
    void *new_buffer;
    int offset;
    struct core_memory_pool *ephemeral_memory;

    /*
     * pack data in this order:
     *
     * - data (count bytes)
     * - real_source
     * - real_tag
     */
    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);
    real_tag = thorium_message_action(message);
    buffer = thorium_message_buffer(message);
    count = thorium_message_count(message);

#ifdef DEBUG_BINOMIAL_TREE
    printf("DEBUG_BINOMIAL_TREE pack_proxy_message count %d source %d action %x\n", count,
                    thorium_actor_name(self),
                    real_tag);
    thorium_message_print(message);

#endif

    new_count = count + sizeof(real_source) + sizeof(real_tag);

    /* use slab allocator */
    new_buffer = core_memory_pool_allocate(ephemeral_memory, new_count);

#ifdef THORIUM_ACTOR_DEBUG
    printf("DEBUG12 core_memory_pool_allocate %p (pack proxy message)\n",
                    new_buffer);
#endif

    if (count > 0)
        core_memory_copy(new_buffer, buffer, count);

    offset = count;
    core_memory_copy((char *)new_buffer + offset, &real_source, sizeof(real_source));
    offset += sizeof(real_source);
    core_memory_copy((char *)new_buffer + offset, &real_tag, sizeof(real_tag));
    offset += sizeof(real_tag);

    thorium_message_init(message, ACTION_PROXY_MESSAGE, new_count, new_buffer);
    thorium_message_set_source(message, real_source);

#if 0
    /* free the old buffer
     */
    core_memory_free(buffer);
    buffer = NULL;
#endif
}
コード例 #3
0
ファイル: dna_kmer.c プロジェクト: gkthiruvathukal/biosal
void biosal_dna_kmer_reverse_complement_self(struct biosal_dna_kmer *self, int kmer_length,
                struct biosal_dna_codec *codec, struct core_memory_pool *memory)
{
#ifdef BIOSAL_DNA_CODEC_HAS_REVERSE_COMPLEMENT_IMPLEMENTATION
    biosal_dna_codec_reverse_complement_in_place(codec, kmer_length, self->encoded_data);

#else
    char *sequence;

    sequence = core_memory_pool_allocate(memory, kmer_length + 1);
    biosal_dna_kmer_get_sequence(self, sequence, kmer_length, codec);

#ifdef BIOSAL_DNA_KMER_DEBUG
    printf("DEBUG %p before %s\n", (void *)self, sequence);
#endif

    biosal_dna_helper_reverse_complement_in_place(sequence);

#ifdef BIOSAL_DNA_KMER_DEBUG
    printf("DEBUG %p after %s\n", (void *)self, sequence);
#endif

    biosal_dna_kmer_destroy(self, memory);
    biosal_dna_kmer_init(self, sequence, codec, memory);

    core_memory_pool_free(memory, sequence);
    sequence = NULL;
#endif
}
コード例 #4
0
ファイル: dna_kmer.c プロジェクト: gkthiruvathukal/biosal
void biosal_dna_kmer_init_random(struct biosal_dna_kmer *sequence, int kmer_length,
        struct biosal_dna_codec *codec, struct core_memory_pool *memory)
{
    char *dna;
    int i;
    int code;

    dna = (char *)core_memory_pool_allocate(memory, kmer_length + 1);

    for (i = 0; i < kmer_length; i++) {
        code = rand() % 4;

        if (code == 0) {
            dna[i] = 'A';
        } else if (code == 1) {
            dna[i] = 'T';
        } else if (code == 2) {
            dna[i] = 'C';
        } else if (code == 3) {
            dna[i] = 'G';
        }
    }

    dna[kmer_length] = '\0';

    biosal_dna_kmer_init(sequence, dna, codec, memory);
    core_memory_pool_free(memory, dna);
}
コード例 #5
0
ファイル: mpi1_pt2pt_transport.c プロジェクト: huyba/biosal
/* \see http://www.malcolmmclean.site11.com/www/MpiTutorial/MPIStatus.html */
int thorium_mpi1_pt2pt_transport_receive(struct thorium_transport *self, struct thorium_message *message)
{
    struct thorium_mpi1_pt2pt_transport *concrete_self;
    char *buffer;
    int count;
    int source;
    int destination;
    int tag;
    int flag;
    MPI_Status status;
    int result;

    concrete_self = thorium_transport_get_concrete_transport(self);
    source = MPI_ANY_SOURCE;
    tag = DUMMY_TAG;

    /* get return value */
    result = MPI_Iprobe(source, tag, concrete_self->comm, &flag, &status);

    if (result != MPI_SUCCESS) {
        return 0;
    }

    if (!flag) {
        return 0;
    }

    /* get return value */
    result = MPI_Get_count(&status, concrete_self->datatype, &count);

    if (result != MPI_SUCCESS) {
        return 0;
    }

    /* actually allocate (slab allocator) a buffer with count bytes ! */
    buffer = core_memory_pool_allocate(self->inbound_message_memory_pool,
                    count * sizeof(char));

    source = status.MPI_SOURCE;

    /* get return value */
    result = MPI_Recv(buffer, count, concrete_self->datatype, source, tag,
                    concrete_self->comm, &status);

    if (result != MPI_SUCCESS) {
        return 0;
    }

    destination = self->rank;

    /*
     * Prepare the message. The worker will be -1 to tell the thorium
     * code that this is not a worker buffer.
     */
    thorium_message_init_with_nodes(message, count, buffer, source, destination);

    return 1;
}
コード例 #6
0
ファイル: dna_kmer.c プロジェクト: gkthiruvathukal/biosal
void biosal_dna_kmer_init_copy(struct biosal_dna_kmer *self, struct biosal_dna_kmer *other, int kmer_length,
                struct core_memory_pool *memory, struct biosal_dna_codec *codec)
{
    int encoded_length;

    encoded_length = biosal_dna_codec_encoded_length(codec, kmer_length);
    self->encoded_data = core_memory_pool_allocate(memory, encoded_length);
    core_memory_copy(self->encoded_data, other->encoded_data, encoded_length);
}
コード例 #7
0
ファイル: vector.c プロジェクト: huyba/biosal
int core_vector_pack_unpack(struct core_vector *self, void *buffer, int operation)
{
    struct core_packer packer;
    int64_t bytes;
    int size;
    struct core_memory_pool *memory;

    core_packer_init(&packer, operation, buffer);

    core_packer_process(&packer, &self->size, sizeof(self->size));

#ifdef CORE_VECTOR_DEBUG
    printf("DEBUG core_vector_pack_unpack operation %d size %d\n",
                    operation, self->size);
#endif

    core_packer_process(&packer, &self->element_size, sizeof(self->element_size));

#ifdef CORE_VECTOR_DEBUG
    printf("DEBUG core_vector_pack_unpack operation %d element_size %d\n",
                    operation, self->element_size);
#endif

    if (operation == CORE_PACKER_OPERATION_UNPACK) {

        size = self->size;
        memory = self->memory;
        core_vector_init(self, self->element_size);

        /*
         * Restore attributes.
         */
        self->size = size;
        self->maximum_size = self->size;
        self->memory = memory;

        if (self->size > 0) {
            self->data = core_memory_pool_allocate(self->memory, self->maximum_size * self->element_size);
            ++self->profile_allocate_calls;
        } else {
            self->data = NULL;
        }
    }

    if (self->size > 0) {

        core_packer_process(&packer, self->data, self->size * self->element_size);
    }

    bytes = core_packer_get_byte_count(&packer);
    core_packer_destroy(&packer);

    return bytes;
}
コード例 #8
0
void test_allocator(struct core_memory_pool *memory)
{
    int i;
    int size;
    void *pointer;
    struct core_vector vector;
    struct core_timer timer;
    uint64_t elapsed;

    i = 1000000;
    size = 45;

    core_vector_init(&vector, sizeof(void *));
    core_timer_init(&timer);

    core_timer_start(&timer);

    while (i--) {
        if (memory != NULL) {
            pointer = core_memory_pool_allocate(memory, size);
        } else {
            pointer = core_memory_allocate(size, -1);
        }

        core_vector_push_back(&vector, &pointer);
    }

    core_timer_stop(&timer);
    elapsed = core_timer_get_elapsed_nanoseconds(&timer);

    if (memory == NULL) {
        printf("Not using memory pool... ");
    } else {
        printf("Using memory pool... ");
    }
    printf("Elapsed : %" PRIu64 " milliseconds\n", elapsed / 1000 / 1000);

    size = core_vector_size(&vector);
    for (i = 0; i < size; ++i) {
        pointer = core_vector_at_as_void_pointer(&vector, i);

        if (memory != NULL) {
            core_memory_pool_free(memory, pointer);
        } else {
            core_memory_free(pointer, -1);
        }
    }
    core_vector_destroy(&vector);
    core_timer_destroy(&timer);
}
コード例 #9
0
ファイル: dna_kmer.c プロジェクト: gkthiruvathukal/biosal
void biosal_dna_kmer_print(struct biosal_dna_kmer *self, int kmer_length,
                struct biosal_dna_codec *codec, struct core_memory_pool *memory)
{
    char *dna_sequence;

    dna_sequence = core_memory_pool_allocate(memory, kmer_length + 1);

    biosal_dna_codec_decode(codec, kmer_length, self->encoded_data, dna_sequence);

    printf("KMER length: %d nucleotides, sequence: %s hash %" PRIu64 "\n", kmer_length,
                   dna_sequence,
                   biosal_dna_kmer_canonical_hash(self, kmer_length, codec, memory));

    core_memory_pool_free(memory, dna_sequence);
    dna_sequence = NULL;
}
コード例 #10
0
ファイル: vector.c プロジェクト: huyba/biosal
void core_vector_reserve(struct core_vector *self, int64_t size)
{
    void *new_data;
    int64_t old_byte_count;
    int64_t new_byte_count;

#ifdef CORE_VECTOR_DEBUG
    printf("DEBUG core_vector_reserve %p %d buckets current_size %d\n",
                    (void *)self,
                    (int)size,
                    (int)self->size);
#endif

    if (size <= self->maximum_size) {
        return;
    }

    new_byte_count = size * self->element_size;
    old_byte_count = self->size * self->element_size;

#ifdef CORE_VECTOR_DEBUG
    printf("DEBUG core_vector_reserve old_byte_count %d new_byte_count %d\n",
                    old_byte_count, new_byte_count);
#endif

    new_data = core_memory_pool_allocate(self->memory, new_byte_count);
    ++self->profile_allocate_calls;

#ifdef CORE_VECTOR_DEBUG
    printf("DEBUG size %d old %p new %p\n", (int)self->size,
                    (void *)self->data, (void *)new_data);
#endif

    /*
     * copy old data
     */
    if (self->size > 0) {
        core_memory_copy(new_data, self->data, old_byte_count);
        core_memory_pool_free(self->memory, self->data);
        ++self->profile_free_calls;

        self->data = NULL;
    }

    self->data = new_data;
    self->maximum_size = size;
}
コード例 #11
0
ファイル: worker.c プロジェクト: huyba/biosal
void *thorium_worker_allocate(struct thorium_worker *self, size_t count)
{
    void *buffer;
    int all;
    int metadata_size;

    metadata_size = THORIUM_MESSAGE_METADATA_SIZE;
    all = count + metadata_size;

    /* use slab allocator to allocate buffer... */
    buffer = (char *)core_memory_pool_allocate(&self->outbound_message_memory_pool,
                    all * sizeof(char));

    self->zero_copy_buffer = buffer;

    return buffer;
}
コード例 #12
0
ファイル: dna_kmer.c プロジェクト: gkthiruvathukal/biosal
void biosal_dna_kmer_init_mock(struct biosal_dna_kmer *sequence, int kmer_length,
                struct biosal_dna_codec *codec, struct core_memory_pool *memory)
{
    char *dna;
    int i;

    dna = (char *)core_memory_pool_allocate(memory, kmer_length + 1);

    for (i = 0; i < kmer_length; i++) {
        dna[i] = 'A';
    }

    dna[kmer_length] = '\0';

    biosal_dna_kmer_init(sequence, dna, codec, memory);
    core_memory_pool_free(memory, dna);
}
コード例 #13
0
ファイル: string.c プロジェクト: huyba/biosal
void core_string_rotate_path(char *sequence, int length, int rotation, int kmer_length,
                struct core_memory_pool *pool)
{
    char *buffer;

    /*
     * Impossible.
     */
    if (length < kmer_length) {
        return;
    }

    /*
     * Simplify the rotation
     */
    rotation %= length;

    buffer = core_memory_pool_allocate(pool, length);

    /*
     * Algorithm:
     *
     * 1. Copy (l - r) from old @ r to new @ 0
     * 2. Copy (r - k + 1) from old @ (k - 1) to new @ (l - r)   (only if (r - k + 1 > 0))
     * 3. Copy (k - 1) from new @ 0 to new @ (l - k + 1)
     */

    core_memory_copy(buffer + 0, sequence + rotation, (length - rotation));

    /*
     * Copy the middle
     * */
    if ((rotation - kmer_length + 1) > 0)
        core_memory_copy(buffer + (length - rotation), sequence + (kmer_length - 1),
                    (rotation - kmer_length + 1));

    core_memory_copy(buffer + (length - kmer_length + 1), buffer + 0, (kmer_length - 1));

    /*
     * Copy the new sequence.
     */
    core_memory_copy(sequence, buffer, length);

    core_memory_pool_free(pool, buffer);
}
コード例 #14
0
ファイル: send_helpers.c プロジェクト: levinas/biosal
void thorium_actor_send_range_vector(struct thorium_actor *actor, struct core_vector *actors,
                int tag, struct core_vector *vector)
{
    struct thorium_message message;
    int count;
    void *buffer;
    struct core_memory_pool *ephemeral_memory;

    ephemeral_memory = thorium_actor_get_ephemeral_memory(actor);
    count = core_vector_pack_size(vector);
    buffer = core_memory_pool_allocate(ephemeral_memory, count);
    core_vector_pack(vector, buffer);
    thorium_message_init(&message, tag, count, buffer);
    thorium_actor_send_range(actor, actors, &message);
    thorium_message_destroy(&message);

    core_memory_pool_free(ephemeral_memory, buffer);
}
コード例 #15
0
ファイル: dna_kmer.c プロジェクト: gkthiruvathukal/biosal
/*
#define BIOSAL_DNA_SEQUENCE_DEBUG
*/
void biosal_dna_kmer_init(struct biosal_dna_kmer *sequence, char *data,
                struct biosal_dna_codec *codec, struct core_memory_pool *memory)
{
    int encoded_length;
    int kmer_length;

    if (data == NULL) {
        sequence->encoded_data = NULL;
        kmer_length = 0;
    } else {

        kmer_length = strlen(data);

        encoded_length = biosal_dna_codec_encoded_length(codec, kmer_length);
        sequence->encoded_data = core_memory_pool_allocate(memory, encoded_length);
        biosal_dna_codec_encode(codec, kmer_length, data, sequence->encoded_data);
    }
}
コード例 #16
0
ファイル: dna_kmer.c プロジェクト: gkthiruvathukal/biosal
int biosal_dna_kmer_pack_unpack(struct biosal_dna_kmer *sequence,
                void *buffer, int operation, int kmer_length,
                struct core_memory_pool *memory, struct biosal_dna_codec *codec)
{
    struct core_packer packer;
    int offset;
    int encoded_length;

    core_packer_init(&packer, operation, buffer);

    /* don't pack the kmer length...
     */
#if 0
    core_packer_process(&packer, kmer_length, sizeof(kmer_length));
#endif

    encoded_length = biosal_dna_codec_encoded_length(codec, kmer_length);

    /* encode in 2 bits instead !
     */
    if (operation == CORE_PACKER_OPERATION_UNPACK) {

        if (kmer_length > 0) {
            sequence->encoded_data = core_memory_pool_allocate(memory, encoded_length);
        } else {
            sequence->encoded_data = NULL;
        }
    }

    if (kmer_length > 0) {
        core_packer_process(&packer, sequence->encoded_data, encoded_length);
    }

    offset = core_packer_get_byte_count(&packer);

    core_packer_destroy(&packer);

    return offset;
}
コード例 #17
0
ファイル: message_multiplexer.c プロジェクト: bioparr/biosal
/*
 * Returns 1 if the message was multiplexed.
 *
 * This is O(1) in regard to the number of thorium nodes.
 */
int thorium_message_multiplexer_multiplex(struct thorium_message_multiplexer *self,
                struct thorium_message *message)
{
    /*
     * If buffer is full, use thorium_node_send_with_transport
     *
     * get count
     *
     * if count is below or equal to the threshold
     *      multiplex the message.
     *      return 1
     *
     * return 0
     */

    int count;
    int current_size;
    int maximum_size;
    int action;
    struct core_memory_pool *pool;
    void *new_buffer;
    int new_count;
    void *buffer;
    int destination_node;
    int destination_actor;
    int new_size;
    int required_size;
    struct thorium_multiplexed_buffer *real_multiplexed_buffer;
    uint64_t time;
    int next_node_in_route;
    int source_node;
    int current_node;

#ifdef DEBUG_MULTIPLEXER
    thorium_printf("multiplex\n");
    thorium_message_print(message);
#endif

    if (CORE_BITMAP_GET_FLAG(self->flags, FLAG_DISABLED)) {
        return 0;
    }

    action = thorium_message_action(message);

    CORE_DEBUGGER_ASSERT(action != ACTION_INVALID);

#ifdef THORIUM_MULTIPLEXER_USE_ACTIONS_TO_SKIP
    /*
     * Don't multiplex already-multiplexed messages.
     */
    if (thorium_multiplexer_policy_is_action_to_skip(self->policy, action)) {
        return 0;
    }
#endif

#ifdef CONFIG_MULTIPLEXER_USE_DECISION_MAKER
    thorium_message_multiplexer_update_timeout(self);
#endif

    ++self->original_message_count;

    count = thorium_message_count(message);

    destination_node = thorium_message_destination_node(message);

    source_node = message->routing_source;
    current_node = self->node->name;
    next_node_in_route = thorium_router_get_next_rank_in_route(&self->router,
                    source_node, current_node, destination_node);

    /*
    thorium_message_print(message);
    thorium_printf("router: source_node %d current_node %d next_node_in_route %d"
                    " destination_node %d\n",
                    source_node, current_node,
                    next_node_in_route, destination_node);
                    */

#ifdef CONFIG_USE_TOPOLOGY_AWARE_AGGREGATION
    /*
     * The next node in the route for this message is
     * next_node_in_route.
     */
    destination_node = next_node_in_route;
#endif

    CORE_DEBUGGER_ASSERT(source_node >= 0);

    real_multiplexed_buffer = core_vector_at(&self->buffers, destination_node);

    CORE_DEBUGGER_ASSERT(real_multiplexed_buffer != NULL);

    required_size = thorium_multiplexed_buffer_required_size(real_multiplexed_buffer, count);

    buffer = thorium_message_buffer(message);
    destination_actor = thorium_message_destination(message);

#ifdef DEBUG_MULTIPLEXER
    thorium_printf("DEBUG multiplex count %d required_size %d action %x\n",
                    count, required_size, action);
#endif

    /*
     * Don't multiplex non-actor messages.
     */
    if (destination_actor == THORIUM_ACTOR_NOBODY) {
        return 0;
    }

#ifdef CORE_DEBUGGER_ASSERT
    if (real_multiplexed_buffer == NULL) {
        thorium_printf("Error action %d destination_node %d destination_actor %d\n", action, destination_node,
                        destination_actor);
    }
#endif

    current_size = thorium_multiplexed_buffer_current_size(real_multiplexed_buffer);
    maximum_size = thorium_multiplexed_buffer_maximum_size(real_multiplexed_buffer);

    /*
     * Don't multiplex large messages.
     */
    if (required_size > maximum_size) {

#ifdef DEBUG_MULTIPLEXER
        thorium_printf("too large required_size %d maximum_size %d\n", required_size, maximum_size);
#endif
        return 0;
    }

    /*
    thorium_printf("MULTIPLEX_MESSAGE\n");
    */

    new_size = current_size + required_size;

    /*
     * Flush now if there is no space left for the <required_size> bytes
     */
    if (new_size > maximum_size) {

#ifdef DEBUG_MULTIPLEXER
        thorium_printf("thorium_message_multiplexer: must FLUSH thorium_message_multiplexer_multiplex required_size %d new_size %d maximum_size %d\n",
                    required_size, new_size, maximum_size);
#endif

        thorium_message_multiplexer_flush(self, destination_node, FORCE_YES_SIZE);
        current_size = thorium_multiplexed_buffer_current_size(real_multiplexed_buffer);

        CORE_DEBUGGER_ASSERT(current_size == 0);
    }

    time = core_timer_get_nanoseconds(&self->timer);

    /*
     * If the buffer is empty before adding the data, it means that it is not
     * in the list of buffers with content and it must be added.
     */
    if (current_size == 0) {

        thorium_multiplexed_buffer_set_time(real_multiplexed_buffer, time);

#ifdef THORIUM_MULTIPLEXER_TRACK_BUFFERS_WITH_CONTENT
        core_set_add(&self->buffers_with_content, &destination_node);
#endif

        /*
         * Add it to the timeline.
         */

#ifdef THORIUM_MULTIPLEXER_USE_TREE
        core_red_black_tree_add_key_and_value(&self->timeline, &time, &destination_node);

#elif defined(THORIUM_MULTIPLEXER_USE_HEAP)
        core_binary_heap_insert(&self->timeline, &time, &destination_node);
#elif defined(THORIUM_MULTIPLEXER_USE_QUEUE)
        core_queue_enqueue(&self->timeline, &destination_node);
#endif

    }

    /*
     * The allocation of buffer is lazy.
     * The current worker is an exporter of small message for the destination
     * "destination_node".
     */
    if (thorium_multiplexed_buffer_buffer(real_multiplexed_buffer) == NULL) {
        pool = thorium_worker_get_outbound_message_memory_pool(self->worker);

        new_count = self->buffer_size_in_bytes + THORIUM_MESSAGE_METADATA_SIZE;
        new_buffer = core_memory_pool_allocate(pool, new_count);

        thorium_multiplexed_buffer_set_buffer(real_multiplexed_buffer, new_buffer);
    }

    /*
    thorium_printf("DEBUG worker_latency %d ns\n",
                    thorium_worker_latency(self->worker));
                    */

    thorium_multiplexed_buffer_append(real_multiplexed_buffer, count, buffer, time);

    /*
     * Try to flush. This only flushes something if the buffer is full.
     */

    if (thorium_message_multiplexer_buffer_is_ready(self, real_multiplexed_buffer)) {

        /*
         * Try to flush here too. This is required in order to satisfy the
         * technical requirement of a DOA limit.
         *
         * Obviously, don't flush if there is some outbound traffic congestion.
         * Otherwise, there will be too many messages on the network.
         */
        if (!thorium_worker_has_outbound_traffic_congestion(self->worker)) {
            thorium_message_multiplexer_flush(self, destination_node, FORCE_YES_SIZE);
        }
    }

    /*
     * Verify invariant.
     */
    CORE_DEBUGGER_ASSERT(thorium_multiplexed_buffer_current_size(real_multiplexed_buffer)<= maximum_size);

    /*
     * Inject the buffer into the worker too.
     */
    return 1;
}
コード例 #18
0
ファイル: assembly_graph_store.c プロジェクト: huyba/biosal
void biosal_assembly_graph_store_get_starting_vertex(struct thorium_actor *self, struct thorium_message *message)
{
    struct biosal_assembly_graph_store *concrete_self;
    struct biosal_dna_kmer transport_kmer;
    struct biosal_dna_kmer storage_kmer;
    struct core_memory_pool *ephemeral_memory;
    struct thorium_message new_message;
    int new_count;
    void *new_buffer;
    char *sequence;
    void *storage_key;
    struct biosal_assembly_vertex *vertex;

    concrete_self = thorium_actor_concrete_actor(self);
    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);

    while (core_map_iterator_has_next(&concrete_self->iterator)) {

        storage_key = NULL;
        vertex = NULL;

        core_map_iterator_next(&concrete_self->iterator, (void **)&storage_key,
                        (void **)&vertex);

        /*
         * Skip the vertex if it does have the status
         * BIOSAL_VERTEX_FLAG_USED.
         */
        if (biosal_assembly_vertex_get_flag(vertex, BIOSAL_VERTEX_FLAG_USED)) {


            continue;
        }

        CORE_DEBUGGER_ASSERT(storage_key != NULL);

#ifdef BIOSAL_ASSEMBLY_GRAPH_STORE_DEBUG_GET_STARTING_VERTEX
        printf("From storage\n");
        biosal_assembly_vertex_print(vertex);

        core_debugger_examine(storage_key, concrete_self->key_length_in_bytes);
#endif

        biosal_dna_kmer_init_empty(&storage_kmer);
        biosal_dna_kmer_unpack(&storage_kmer, storage_key, concrete_self->kmer_length,
                        ephemeral_memory,
                        &concrete_self->storage_codec);

#ifdef BIOSAL_ASSEMBLY_GRAPH_STORE_DEBUG_GET_STARTING_VERTEX
        printf("DEBUG starting kmer Storage kmer hash %" PRIu64 "\n",
                        biosal_dna_kmer_hash(&storage_kmer, concrete_self->kmer_length,
                                &concrete_self->storage_codec));

        biosal_dna_kmer_print(&storage_kmer, concrete_self->kmer_length, &concrete_self->storage_codec,
                    ephemeral_memory);
#endif

        sequence = core_memory_pool_allocate(ephemeral_memory, concrete_self->kmer_length + 1);

        biosal_dna_kmer_get_sequence(&storage_kmer, sequence, concrete_self->kmer_length,
                        &concrete_self->storage_codec);

#ifdef BIOSAL_ASSEMBLY_GRAPH_STORE_DEBUG_GET_STARTING_VERTEX
        printf("SEQUENCE %s\n", sequence);
#endif

        biosal_dna_kmer_init(&transport_kmer, sequence, &concrete_self->transport_codec,
                        ephemeral_memory);

        new_count = biosal_dna_kmer_pack_size(&transport_kmer, concrete_self->kmer_length,
                        &concrete_self->transport_codec);
        new_buffer = thorium_actor_allocate(self, new_count);

        biosal_dna_kmer_pack(&transport_kmer, new_buffer, concrete_self->kmer_length,
                        &concrete_self->transport_codec);

#ifdef BIOSAL_ASSEMBLY_GRAPH_STORE_DEBUG_GET_STARTING_VERTEX
        printf("Packed version:\n");

        core_debugger_examine(new_buffer, new_count);

        printf("TRANSPORT Kmer new_count %d\n", new_count);

        biosal_dna_kmer_print(&transport_kmer, concrete_self->kmer_length, &concrete_self->transport_codec,
                    ephemeral_memory);
#endif

        thorium_message_init(&new_message, ACTION_ASSEMBLY_GET_STARTING_KMER_REPLY,
                        new_count, new_buffer);

        thorium_actor_send_reply(self, &new_message);

        thorium_message_destroy(&new_message);

        biosal_dna_kmer_destroy(&transport_kmer, ephemeral_memory);

        core_memory_pool_free(ephemeral_memory, sequence);

        biosal_dna_kmer_destroy(&storage_kmer, ephemeral_memory);

        return;
    }

    /*
     * An empty reply means that the store has nothing more to yield.
     */
    thorium_actor_send_reply_empty(self, ACTION_ASSEMBLY_GET_STARTING_KMER_REPLY);
}
コード例 #19
0
ファイル: assembly_graph_store.c プロジェクト: huyba/biosal
void biosal_assembly_graph_store_push_arc_block(struct thorium_actor *self, struct thorium_message *message)
{
    struct biosal_assembly_graph_store *concrete_self;
    int size;
    int i;
    void *buffer;
    int count;
    struct biosal_assembly_arc_block input_block;
    struct biosal_assembly_arc *arc;
    struct core_memory_pool *ephemeral_memory;
    struct core_vector *input_arcs;
    char *sequence;
    void *key;

#if 0
    /*
     * Don't do anything to rule out that this is the problem.
     */
    thorium_actor_send_reply_empty(self, ACTION_ASSEMBLY_PUSH_ARC_BLOCK_REPLY);
    return;
#endif

    concrete_self = thorium_actor_concrete_actor(self);
    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);

    sequence = core_memory_pool_allocate(ephemeral_memory, concrete_self->kmer_length + 1);

    ++concrete_self->received_arc_block_count;

    count = thorium_message_count(message);
    buffer = thorium_message_buffer(message);

    biosal_assembly_arc_block_init(&input_block, ephemeral_memory, concrete_self->kmer_length,
                    &concrete_self->transport_codec);

    biosal_assembly_arc_block_unpack(&input_block, buffer, concrete_self->kmer_length,
                    &concrete_self->transport_codec, ephemeral_memory);

    input_arcs = biosal_assembly_arc_block_get_arcs(&input_block);
    size = core_vector_size(input_arcs);

    if (!concrete_self->printed_arc_size) {
        printf("DEBUG ARC DELIVERY %d bytes, %d arcs\n",
                    count, size);

        concrete_self->printed_arc_size = 1;
    }

    key = core_memory_pool_allocate(ephemeral_memory, concrete_self->key_length_in_bytes);

    for (i = 0; i < size; i++) {

        arc = core_vector_at(input_arcs, i);

#ifdef BIOSAL_ASSEMBLY_ADD_ARCS
        biosal_assembly_graph_store_add_arc(self, arc, sequence, key);
#endif

        ++concrete_self->received_arc_count;
    }

    core_memory_pool_free(ephemeral_memory, key);

    biosal_assembly_arc_block_destroy(&input_block, ephemeral_memory);

    /*
     *
     * Add the arcs to the graph
     */

    thorium_actor_send_reply_empty(self, ACTION_ASSEMBLY_PUSH_ARC_BLOCK_REPLY);

    core_memory_pool_free(ephemeral_memory, sequence);
}
コード例 #20
0
ファイル: assembly_graph_store.c プロジェクト: huyba/biosal
void biosal_assembly_graph_store_push_kmer_block(struct thorium_actor *self, struct thorium_message *message)
{
    struct core_memory_pool *ephemeral_memory;
    struct biosal_dna_kmer_frequency_block block;
    struct biosal_assembly_vertex *bucket;
    void *packed_kmer;
    struct core_map_iterator iterator;
    struct biosal_assembly_graph_store *concrete_self;
    /*int tag;*/
    void *key;
    struct core_map *kmers;
    struct biosal_dna_kmer kmer;
    void *buffer;
    int count;
    struct biosal_dna_kmer encoded_kmer;
    char *raw_kmer;
    int period;
    struct biosal_dna_kmer *kmer_pointer;
    int *frequency;

    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);
    concrete_self = thorium_actor_concrete_actor(self);
    /*tag = thorium_message_action(message);*/
    buffer = thorium_message_buffer(message);
    count = thorium_message_count(message);

    /*
     * Handler for PUSH_DATA
     */

    biosal_dna_kmer_frequency_block_init(&block, concrete_self->kmer_length,
                    ephemeral_memory, &concrete_self->transport_codec, 0);

    biosal_dna_kmer_frequency_block_unpack(&block, buffer, ephemeral_memory,
                    &concrete_self->transport_codec);

    key = core_memory_pool_allocate(ephemeral_memory, concrete_self->key_length_in_bytes);

    kmers = biosal_dna_kmer_frequency_block_kmers(&block);
    core_map_iterator_init(&iterator, kmers);

    period = 2500000;

    raw_kmer = core_memory_pool_allocate(thorium_actor_get_ephemeral_memory(self),
                    concrete_self->kmer_length + 1);

    if (!concrete_self->printed_vertex_size) {

        printf("DEBUG VERTEX DELIVERY %d bytes\n", count);

        concrete_self->printed_vertex_size = 1;
    }

    while (core_map_iterator_has_next(&iterator)) {

        /*
         * add kmers to store
         */
        core_map_iterator_next(&iterator, (void **)&packed_kmer, (void **)&frequency);

        /* Store the kmer in 2 bit encoding
         */

        biosal_dna_kmer_init_empty(&kmer);
        biosal_dna_kmer_unpack(&kmer, packed_kmer, concrete_self->kmer_length,
                    ephemeral_memory,
                    &concrete_self->transport_codec);

        kmer_pointer = &kmer;

        if (concrete_self->codec_are_different) {
            /*
             * Get a copy of the sequence
             */
            biosal_dna_kmer_get_sequence(kmer_pointer, raw_kmer, concrete_self->kmer_length,
                        &concrete_self->transport_codec);


            biosal_dna_kmer_init(&encoded_kmer, raw_kmer, &concrete_self->storage_codec,
                        thorium_actor_get_ephemeral_memory(self));
            kmer_pointer = &encoded_kmer;
        }

        biosal_dna_kmer_pack_store_key(kmer_pointer, key,
                        concrete_self->kmer_length, &concrete_self->storage_codec,
                        thorium_actor_get_ephemeral_memory(self));

#ifdef BIOSAL_DEBUG_ISSUE_540
        if (strcmp(raw_kmer, "AGCTGGTAGTCATCACCAGACTGGAACAG") == 0
                        || strcmp(raw_kmer, "CGCGATCTGTTGCTGGGCCTAACGTGGTA") == 0
                        || strcmp(raw_kmer, "TACCACGTTAGGCCCAGCAACAGATCGCG") == 0) {
            printf("Examine store key for %s\n", raw_kmer);

            core_debugger_examine(key, concrete_self->key_length_in_bytes);
        }
#endif

        bucket = core_map_get(&concrete_self->table, key);

        if (bucket == NULL) {
            /* This is the first time that this kmer is seen.
             */
            bucket = core_map_add(&concrete_self->table, key);

            biosal_assembly_vertex_init(bucket);

#if 0
            printf("DEBUG303 ADD_KEY");
            biosal_dna_kmer_print(&encoded_kmer, concrete_self->kmer_length,
                            &concrete_self->storage_codec, ephemeral_memory);
#endif
        }

        if (concrete_self->codec_are_different) {
            biosal_dna_kmer_destroy(&encoded_kmer,
                        thorium_actor_get_ephemeral_memory(self));
        }

        biosal_dna_kmer_destroy(&kmer, ephemeral_memory);

        biosal_assembly_vertex_increase_coverage_depth(bucket, *frequency);

        if (concrete_self->received >= concrete_self->last_received + period) {
            printf("%s/%d received %" PRIu64 " kmers so far,"
                            " store has %" PRIu64 " canonical kmers, %" PRIu64 " kmers\n",
                        thorium_actor_script_name(self),
                            thorium_actor_name(self), concrete_self->received,
                            core_map_size(&concrete_self->table),
                            2 * core_map_size(&concrete_self->table));

            concrete_self->last_received = concrete_self->received;
        }

        concrete_self->received += *frequency;
    }

    core_memory_pool_free(ephemeral_memory, key);
    core_memory_pool_free(ephemeral_memory, raw_kmer);

    core_map_iterator_destroy(&iterator);
    biosal_dna_kmer_frequency_block_destroy(&block, thorium_actor_get_ephemeral_memory(self));

    thorium_actor_send_reply_empty(self, ACTION_PUSH_KMER_BLOCK_REPLY);
}
コード例 #21
0
ファイル: message_multiplexer.c プロジェクト: bioparr/biosal
/*
 * Returns 1 if the message was demultiplexed.
 *
 * This is O(1) in regard to the number of thorium nodes.
 */
int thorium_message_multiplexer_demultiplex(struct thorium_message_multiplexer *self,
                struct thorium_message *message)
{
    /*
     * Algorithm:
     *
     * get tag.
     * if tag is ACTION_MULTIPLEXER_MESSAGE
     *     for every enclosed message
     *         call thorium_node_prepare_received_message
     *         call thorium_node_dispatch_message()
     *     return 1
     *
     * return 0
     */

    int count;
    char *buffer;
    struct thorium_message new_message;
    int new_count;
    void *new_buffer;
    int position;
    struct core_memory_pool *pool;
    int messages;
    int tag;
    int source_node;
    int destination_node;
    int current_node;
    int routing_destination;

#ifdef DEBUG_MULTIPLEXER
    thorium_printf("demultiplex message\n");
    thorium_message_print(message);
#endif

    if (CORE_BITMAP_GET_FLAG(self->flags, FLAG_DISABLED)) {
        return 0;
    }

    tag = thorium_message_action(message);

    if (tag != ACTION_MULTIPLEXER_MESSAGE) {
        return 0;
    }

    /*
    thorium_printf("MULTIPLEXER demultiplex\n");
    */

    messages = 0;
    tracepoint(thorium_node, demultiplex_enter, self->node->name,
                    self->node->tick, messages);

    source_node = thorium_message_source_node(message);
    destination_node = thorium_message_destination_node(message);

    /*
     * Remove the metadata from the count.
     */
    thorium_message_remove_metadata_from_count(message);

    count = thorium_message_count(message);

    buffer = thorium_message_buffer(message);

    pool = thorium_worker_get_outbound_message_memory_pool(self->worker);

    position = 0;

    /*
     * Inject a message for each enclosed message.
     */
    while (position < count) {
        core_memory_copy(&new_count, buffer + position, sizeof(new_count));
        position += sizeof(new_count);

        new_buffer = core_memory_pool_allocate(pool, new_count);
        core_memory_copy(new_buffer, buffer + position, new_count);

        thorium_message_init_with_nodes(&new_message, new_count, new_buffer,
                        source_node, destination_node);

        thorium_node_prepare_received_message(self->node, &new_message);

        /*
         * For these demultiplexed messages, there are 2 outcomes:
         *
         * 1) the message must be delivered locally;
         * 2) the message must be forward because this is a middle node in
         *    the route.
         */
        /*
        thorium_printf("demultiplex: \n");
        thorium_message_print(&new_message);
        thorium_printf("\n");
*/
        /*
         * Mark the message for recycling.
         */
        thorium_message_set_worker(&new_message, thorium_worker_name(self->worker));

#ifdef CORE_DEBUGGER_ASSERT_ENABLED
        if (thorium_message_action(&new_message) == ACTION_INVALID) {
            thorium_printf("Error invalid action DEMUL Multiplexer position %d count %d new_count %d\n",
                            position, count, new_count);
            thorium_message_print(&new_message);
        }
#endif

        CORE_DEBUGGER_ASSERT(thorium_message_action(&new_message) != ACTION_INVALID);

        /*
        thorium_printf("DEMULTIPLEX_MESSAGE\n");
        */

        /*
        thorium_printf("demultiplex, local delivery: \n");
        thorium_message_print(&new_message);
        */

        current_node = self->node->name;
        routing_destination = new_message.routing_destination;

        CORE_DEBUGGER_ASSERT(routing_destination >= 0);

        /*
         * This is a local delivery, nothing to see here.
         */
        if (routing_destination == current_node) {

            thorium_worker_send_local_delivery(self->worker, &new_message);

        /*
         * Otherwise, get the next node in the route and send the
         * payload there since we can not do anything with it here.
         */
        } else {

            /*
             * Export the message to another node.
             * To do this, use an exporter worker.
             */
            thorium_worker_send_for_multiplexer(self->worker,
                            &new_message);
        }

        /*
        thorium_message_destroy(&new_message);
        */

        position += new_count;
        ++messages;
    }

    CORE_DEBUGGER_ASSERT(messages > 0);

#ifdef DEBUG_MULTIPLEXER
    thorium_printf("thorium_message_multiplexer_demultiplex %d messages\n",
                    messages);
#endif

    tracepoint(thorium_node, demultiplex_exit, self->node->name,
                    self->node->tick, messages);

    return 1;
}
コード例 #22
0
ファイル: assembly_graph_store.c プロジェクト: huyba/biosal
void biosal_assembly_graph_store_mark_vertex_as_visited(struct thorium_actor *self, struct thorium_message *message)
{
    struct biosal_assembly_graph_store *concrete_self;
    char *buffer;
    int source;
    int path_index;
    char *sequence;
    struct core_memory_pool *ephemeral_memory;
    struct biosal_dna_kmer kmer;
    struct biosal_dna_kmer storage_kmer;
    struct biosal_assembly_vertex *canonical_vertex;
    int position;
    void *key;
    int force;

    force = 1;
    position = 0;
    concrete_self = thorium_actor_concrete_actor(self);
    source = thorium_message_source(message);
    buffer = thorium_message_buffer(message);
    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);

    /*
     * Get the kmer.
     */
    biosal_dna_kmer_init_empty(&kmer);

    position += biosal_dna_kmer_unpack(&kmer, buffer, concrete_self->kmer_length,
                ephemeral_memory, &concrete_self->transport_codec);
    sequence = core_memory_pool_allocate(ephemeral_memory, concrete_self->kmer_length + 1);
    biosal_dna_kmer_get_sequence(&kmer, sequence, concrete_self->kmer_length,
                        &concrete_self->transport_codec);
    biosal_dna_kmer_init(&storage_kmer, sequence, &concrete_self->storage_codec,
                        ephemeral_memory);

    /*
     * Get store key
     */
    key = core_memory_pool_allocate(ephemeral_memory, concrete_self->key_length_in_bytes);
    biosal_dna_kmer_pack_store_key(&storage_kmer, key, concrete_self->kmer_length, &concrete_self->storage_codec,
                        ephemeral_memory);

    /* Get vertex. */
    canonical_vertex = core_map_get(&concrete_self->table, key);

    biosal_dna_kmer_destroy(&kmer, ephemeral_memory);
    biosal_dna_kmer_destroy(&storage_kmer, ephemeral_memory);
    core_memory_pool_free(ephemeral_memory, key);
    core_memory_pool_free(ephemeral_memory, sequence);

    position += thorium_message_unpack_int(message, position, &path_index);
    /*
     * At this point, mark the vertex with flag BIOSAL_VERTEX_FLAG_USED
     * so that any other actor that attempt to grab it will have to communicate
     * with the actor.
     */

    /*
     * This is a good idea to always update with the last one.
     */
    if (force || !biosal_assembly_vertex_get_flag(canonical_vertex, BIOSAL_VERTEX_FLAG_USED)) {
        biosal_assembly_graph_store_mark_as_used(self, canonical_vertex, source, path_index);
    }
#if 0
#endif

    thorium_actor_send_reply_empty(self, ACTION_MARK_VERTEX_AS_VISITED_REPLY);
}
コード例 #23
0
ファイル: simple_queue.c プロジェクト: bioparr/biosal
struct core_simple_queue_item *core_simple_queue_allocate_item(struct core_simple_queue *self)
{
#ifdef USE_BLOCK_ALLOCATION
    struct core_simple_queue_item *item;
    int unit_size;
    int count;
    int block_size;
    int i;
    struct core_simple_queue_item *allocation;

    /*
     * Use the linked list of garbage-collected items.
     */
    if (self->garbage_ != NULL) {
        item = self->garbage_;

        /* Move the garbage pointer.
         */
        self->garbage_ = self->garbage_->next_;

        item->data_ = ((char *)item) + sizeof(struct core_simple_queue_item);
        item->next_ = NULL;

        return item;
    }

    unit_size = sizeof(struct core_simple_queue_item) + self->bytes_per_unit_;

    block_size = 32768;
    count = block_size / unit_size;

    block_size = count * unit_size;

    allocation = core_memory_pool_allocate(self->pool_, block_size);

    allocation->next_ = self->allocations_;
    self->allocations_ = allocation;

#ifdef DEBUG_QUEUE
    printf("generate %d items from %d bytes\n", count - 1, block_size);
#endif

    /*
     * Generate items in garbage list;
     */
    i = 0;

    /*
     * Skip the first one since it is used for tracking allocations.
     */
    ++i;
    while (i < count) {
        item = (void *)(((char *)allocation) + i * unit_size);
        item->next_ = self->garbage_;
        self->garbage_ = item;
        ++i;
    }

    /*
     * Recursive call.
     * There is at most one recursive call.
     */
    return core_simple_queue_allocate_item(self);

#else
    int unit_size;
    struct core_simple_queue_item *item;

    unit_size = sizeof(struct core_simple_queue_item) + self->bytes_per_unit_;

    item = core_memory_pool_allocate(self->pool_, unit_size);
    item->next_ = NULL;
    item->data_ = ((char *)item) + sizeof(struct core_simple_queue_item);

    return item;
#endif
}
コード例 #24
0
ファイル: assembly_graph_store.c プロジェクト: huyba/biosal
void biosal_assembly_graph_store_print(struct thorium_actor *self)
{
    struct core_map_iterator iterator;
    struct biosal_dna_kmer kmer;
    void *key;
    struct biosal_assembly_vertex *value;
    int coverage;
    char *sequence;
    struct biosal_assembly_graph_store *concrete_self;
    int maximum_length;
    int length;
    struct core_memory_pool *ephemeral_memory;

    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);
    concrete_self = thorium_actor_concrete_actor(self);

    core_map_iterator_init(&iterator, &concrete_self->table);

    printf("map size %d\n", (int)core_map_size(&concrete_self->table));

    maximum_length = 0;

    while (core_map_iterator_has_next(&iterator)) {
        core_map_iterator_next(&iterator, (void **)&key, (void **)&value);

        biosal_dna_kmer_init_empty(&kmer);
        biosal_dna_kmer_unpack(&kmer, key, concrete_self->kmer_length,
                        thorium_actor_get_ephemeral_memory(self),
                        &concrete_self->storage_codec);

        length = biosal_dna_kmer_length(&kmer, concrete_self->kmer_length);

        /*
        printf("length %d\n", length);
        */
        if (length > maximum_length) {
            maximum_length = length;
        }
        biosal_dna_kmer_destroy(&kmer, thorium_actor_get_ephemeral_memory(self));
    }

    /*
    printf("MAx length %d\n", maximum_length);
    */

    sequence = core_memory_pool_allocate(ephemeral_memory, maximum_length + 1);
    sequence[0] = '\0';
    core_map_iterator_destroy(&iterator);
    core_map_iterator_init(&iterator, &concrete_self->table);

    while (core_map_iterator_has_next(&iterator)) {
        core_map_iterator_next(&iterator, (void **)&key, (void **)&value);

        biosal_dna_kmer_init_empty(&kmer);
        biosal_dna_kmer_unpack(&kmer, key, concrete_self->kmer_length,
                        thorium_actor_get_ephemeral_memory(self),
                        &concrete_self->storage_codec);

        biosal_dna_kmer_get_sequence(&kmer, sequence, concrete_self->kmer_length,
                        &concrete_self->storage_codec);

        coverage = biosal_assembly_vertex_coverage_depth(value);

        printf("Sequence %s Coverage %d\n", sequence, coverage);

        biosal_dna_kmer_destroy(&kmer, thorium_actor_get_ephemeral_memory(self));
    }

    core_map_iterator_destroy(&iterator);
    core_memory_pool_free(ephemeral_memory, sequence);
}