コード例 #1
0
ファイル: send_helpers.c プロジェクト: huyba/biosal
void thorium_actor_send_range_default(struct thorium_actor *actor, struct core_vector *actors,
                int first, int last,
                struct thorium_message *message)
{
#ifdef USE_BINOMIAL_TREE
    struct core_vector destinations;
    struct core_memory_pool *ephemeral_memory;
    int name;

    ephemeral_memory = thorium_actor_get_ephemeral_memory(actor);
    core_vector_init(&destinations, sizeof(int));
    core_vector_set_memory_pool(&destinations, ephemeral_memory);
    core_vector_copy_range(actors, first, last, &destinations);

    /*
     * Set the source now.
     */
    name = thorium_actor_name(actor);
    thorium_message_set_source(message, name);

    thorium_actor_send_range_binomial_tree(actor, &destinations, message);

    core_vector_destroy(&destinations);
#else

    thorium_actor_send_range_loop(actor, actors, first, last, message);
#endif
}
コード例 #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
ファイル: send_helpers.c プロジェクト: levinas/biosal
void thorium_actor_send_range_default(struct thorium_actor *actor, struct core_vector *actors,
                int first, int last,
                struct thorium_message *message)
{
    int use_binomial_tree;
    struct core_vector destinations;
    struct core_memory_pool *ephemeral_memory;
    int name;
    int action;

    action = thorium_message_action(message);
    use_binomial_tree = 0;

#ifdef USE_BINOMIAL_TREE

    /*
     * ACTION_ASK_TO_STOP basically kills actors (if they agree to).
     * It is a bad idea to use a binomial tree to send this death signal
     * since intermediate actors can die before acting as relays.
     */
    if (action != ACTION_ASK_TO_STOP)
        use_binomial_tree = 1;
#endif

    if (!use_binomial_tree) {
        thorium_actor_send_range_loop(actor, actors, first, last, message);
        return;
    }

    tracepoint(thorium_binomial_tree, send_range, message, (int)core_vector_size(actors));

    /*
     * Otherwise, use the binomial tree code path. This algorithm is better since it distributed
     * the sending operations intot a binomial tree where there are a lot of intermediate
     * actors (to be exact, the number of intermediate actors is close to log2(actors.size)).
     */
    ephemeral_memory = thorium_actor_get_ephemeral_memory(actor);
    core_vector_init(&destinations, sizeof(int));
    core_vector_set_memory_pool(&destinations, ephemeral_memory);

    CORE_DEBUGGER_ASSERT(core_vector_empty(&destinations));

    core_vector_copy_range(actors, first, last, &destinations);

    /*
     * Set the source now.
     */
    name = thorium_actor_name(actor);
    thorium_message_set_source(message, name);

    thorium_actor_send_range_binomial_tree(actor, &destinations, message);

    core_vector_destroy(&destinations);
}
コード例 #4
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;
}
コード例 #5
0
ファイル: assembly_graph_store.c プロジェクト: huyba/biosal
void biosal_assembly_graph_store_set_vertex_flag(struct thorium_actor *self,
                struct thorium_message *message)
{
    char *buffer;
    int count;
    int flag;
    struct biosal_dna_kmer transport_kmer;
    struct biosal_assembly_vertex *vertex;
    struct biosal_assembly_graph_store *concrete_self;
    struct core_memory_pool *ephemeral_memory;
    int position;

    concrete_self = thorium_actor_concrete_actor(self);
    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);
    biosal_dna_kmer_init_empty(&transport_kmer);
    buffer = thorium_message_buffer(message);
    count = thorium_message_count(message);

    position = 0;
    position += biosal_dna_kmer_unpack(&transport_kmer, buffer, concrete_self->kmer_length,
                    ephemeral_memory, &concrete_self->transport_codec);
    core_memory_copy(&flag, buffer + position, sizeof(flag));
    position += sizeof(flag);
    CORE_DEBUGGER_ASSERT_IS_EQUAL_INT(position, count);

    CORE_DEBUGGER_ASSERT(flag >= BIOSAL_VERTEX_FLAG_START_VALUE);
    CORE_DEBUGGER_ASSERT(flag <= BIOSAL_VERTEX_FLAG_END_VALUE);

    if (flag == BIOSAL_VERTEX_FLAG_UNITIG) {
        ++concrete_self->unitig_vertex_count;
    }

#if 0
    printf("DEBUG ACTION_SET_VERTEX_FLAG %d\n", flag);
#endif
    vertex = biosal_assembly_graph_store_find_vertex(self, &transport_kmer);

    CORE_DEBUGGER_ASSERT_NOT_NULL(vertex);

    biosal_dna_kmer_destroy(&transport_kmer, ephemeral_memory);

    biosal_assembly_vertex_set_flag(vertex, flag);

    thorium_actor_send_reply_empty(self, ACTION_SET_VERTEX_FLAG_REPLY);
}
コード例 #6
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);
}
コード例 #7
0
ファイル: input_stream.c プロジェクト: huyba/biosal
void biosal_input_stream_count_reply_mock(struct thorium_actor *self, struct thorium_message *message)
{
    struct biosal_input_stream *concrete_self;
    void *buffer;
    int count;
    struct core_vector mega_blocks;
    char *file;
    struct core_memory_pool *ephemeral_memory;
    uint64_t result;
    struct biosal_mega_block *block;

    concrete_self = (struct biosal_input_stream *)thorium_actor_concrete_actor(self);
    buffer = thorium_message_buffer(message);
    count = thorium_message_count(message);
    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);

    core_vector_init(&mega_blocks, 0);
    core_vector_set_memory_pool(&mega_blocks, ephemeral_memory);
    core_vector_unpack(&mega_blocks, buffer);

    block = core_vector_at_last(&mega_blocks);

    result = biosal_mega_block_get_entries(block);

#if 0
    file = core_string_get(&concrete_self->file_for_parallel_counting);
#endif

    file = concrete_self->file_name;

    printf("%s/%d COUNT_IN_PARALLEL result for %s is %" PRIu64 "\n",
                    thorium_actor_script_name(self),
                    thorium_actor_name(self),
                    file,
                    result);

    core_vector_destroy(&mega_blocks);

    thorium_actor_send_buffer(self, concrete_self->controller,
                    ACTION_INPUT_COUNT_IN_PARALLEL_REPLY, count, buffer);
}
コード例 #8
0
ファイル: assembly_graph_store.c プロジェクト: huyba/biosal
void biosal_assembly_graph_store_yield_reply(struct thorium_actor *self, struct thorium_message *message)
{
    struct biosal_dna_kmer kmer;
    void *key;
    struct biosal_assembly_vertex *value;
    int coverage;
    int customer;
    uint64_t *count;
    int new_count;
    void *new_buffer;
    struct thorium_message new_message;
    struct core_memory_pool *ephemeral_memory;
    struct biosal_assembly_graph_store *concrete_self;
    int i;
    int max;

    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);
    concrete_self = thorium_actor_concrete_actor(self);
    customer = concrete_self->customer;

#if 0
    printf("YIELD REPLY\n");
#endif

    i = 0;
    max = 1024;

    key = NULL;
    value = NULL;

    while (i < max
                    && core_map_iterator_has_next(&concrete_self->iterator)) {

        core_map_iterator_next(&concrete_self->iterator, (void **)&key, (void **)&value);

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

        coverage = biosal_assembly_vertex_coverage_depth(value);

        count = (uint64_t *)core_map_get(&concrete_self->coverage_distribution, &coverage);

        if (count == NULL) {

            count = (uint64_t *)core_map_add(&concrete_self->coverage_distribution, &coverage);

            (*count) = 0;
        }

        /* increment for the lowest kmer (canonical) */
        (*count)++;

        biosal_dna_kmer_destroy(&kmer, ephemeral_memory);

        ++i;
    }

    /* yield again if the iterator is not at the end
     */
    if (core_map_iterator_has_next(&concrete_self->iterator)) {

#if 0
        printf("yield ! %d\n", i);
#endif

        thorium_actor_send_to_self_empty(self, ACTION_YIELD);

        return;
    }

    /*
    printf("ready...\n");
    */

    core_map_iterator_destroy(&concrete_self->iterator);

    new_count = core_map_pack_size(&concrete_self->coverage_distribution);

    new_buffer = thorium_actor_allocate(self, new_count);

    core_map_pack(&concrete_self->coverage_distribution, new_buffer);

    printf("SENDING %s/%d sends map to %d, %d bytes / %d entries\n",
                        thorium_actor_script_name(self),
                    thorium_actor_name(self),
                    customer, new_count,
                    (int)core_map_size(&concrete_self->coverage_distribution));

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

    thorium_actor_send(self, customer, &new_message);
    thorium_message_destroy(&new_message);

    core_map_destroy(&concrete_self->coverage_distribution);

    thorium_actor_send_empty(self, concrete_self->source,
                            ACTION_PUSH_DATA_REPLY);
}
コード例 #9
0
ファイル: input_stream.c プロジェクト: huyba/biosal
void biosal_input_stream_push_sequences(struct thorium_actor *actor,
                struct thorium_message *message)
{
    struct biosal_input_command command;
    void *buffer;
    int store_name;
    uint64_t store_first;
    uint64_t store_last;
    int sequences_to_read;
    void *new_buffer;
    int new_count;
    struct thorium_message new_message;
    void *buffer_for_sequence;
    struct biosal_dna_sequence dna_sequence;
    /*struct core_vector *command_entries;*/
    int has_sequence;
    int i;
    struct biosal_input_stream *concrete_self;

#ifdef BIOSAL_INPUT_STREAM_DEBUG
    int count;
    int actual_count;
#endif

    /* answer immediately
     */
    thorium_actor_send_reply_empty(actor, ACTION_INPUT_PUSH_SEQUENCES_READY);
    has_sequence = 1;

#ifdef BIOSAL_INPUT_STREAM_DEBUG
    printf("DEBUG stream/%d biosal_input_stream_push_sequences entering...\n",
                    thorium_actor_name(actor));
#endif


    buffer = thorium_message_buffer(message);

    concrete_self = (struct biosal_input_stream *)thorium_actor_concrete_actor(actor);

    biosal_input_command_init_empty(&command);
    biosal_input_command_unpack(&command, buffer, thorium_actor_get_ephemeral_memory(actor),
                    &concrete_self->codec);

#ifdef BIOSAL_INPUT_STREAM_DEBUG
    count = thorium_message_count(message);
    printf("DEBUG biosal_input_stream_push_sequences after unpack, count %d:\n",
                    count);

    biosal_input_command_print(&command);
#endif

    store_name = biosal_input_command_store_name(&command);
    store_first = biosal_input_command_store_first(&command);
    store_last = biosal_input_command_store_last(&command);

    sequences_to_read = store_last - store_first + 1;

#ifdef BIOSAL_INPUT_STREAM_DEBUG
    printf("DEBUG biosal_input_stream_push_sequences received ACTION_INPUT_PUSH_SEQUENCES\n");
    printf("DEBUG Command before sending it\n");

    biosal_input_command_print(&command);
#endif

    /*
     * add sequences to the input command
     */

    buffer_for_sequence = concrete_self->buffer_for_sequence;
    /*command_entries = biosal_input_command_entries(&command);*/

    i = 0;
    /* TODO: actually load something
     */
    while (sequences_to_read-- && has_sequence) {
        has_sequence = biosal_input_proxy_get_sequence(&concrete_self->proxy,
                            buffer_for_sequence);

        biosal_dna_sequence_init(&dna_sequence, buffer_for_sequence,
                        &concrete_self->codec, thorium_actor_get_ephemeral_memory(actor));

        biosal_input_command_add_entry(&command, &dna_sequence, &concrete_self->codec,
                        thorium_actor_get_ephemeral_memory(actor));

        biosal_dna_sequence_destroy(&dna_sequence, thorium_actor_get_ephemeral_memory(actor));

        i++;
    }

#ifdef BIOSAL_INPUT_STREAM_DEBUG
    printf("DEBUG prepared %d sequences for command\n",
                    i);
    biosal_input_command_print(&command);
#endif

    new_count = biosal_input_command_pack_size(&command,
                    &concrete_self->codec);

    new_buffer = thorium_actor_allocate(actor, new_count);

    biosal_input_command_pack(&command, new_buffer, &concrete_self->codec);

#ifdef BIOSAL_INPUT_STREAM_DEBUG
    actual_count = biosal_input_command_pack(&command, new_buffer);
    printf("DEBUG123 new_count %d actual_count %d\n", new_count,
                    actual_count);
#endif

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

#ifdef BIOSAL_INPUT_STREAM_DEBUG
    printf("DEBUG biosal_input_stream_push_sequences sending ACTION_PUSH_SEQUENCE_DATA_BLOCK to %d\n",
                    store_name);
#endif

    thorium_actor_send(actor, store_name, &new_message);

    /*
     * send sequences to store.
     * The required information is the input command
     */
    /*
    thorium_actor_send_reply_empty(actor, ACTION_INPUT_PUSH_SEQUENCES_REPLY);
    */

    /* free memory
     */

#ifdef BIOSAL_INPUT_STREAM_DEBUG
    printf("DEBUG freeing %d entries\n",
                    (int)core_vector_size(command_entries));
#endif

    biosal_input_command_destroy(&command, thorium_actor_get_ephemeral_memory(actor));

#if 0
    for (i = 0; i < core_vector_size(command_entries); i++) {
        a_sequence = (struct biosal_dna_sequence *)core_vector_at(command_entries, i);

        biosal_dna_sequence_destroy(a_sequence, thorium_actor_get_ephemeral_memory(actor));
    }

    core_vector_destroy(command_entries);
#endif

#ifdef BIOSAL_INPUT_STREAM_DEBUG
    printf("DEBUG biosal_input_stream_push_sequences EXIT\n");
#endif

}
コード例 #10
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);
}
コード例 #11
0
ファイル: assembly_graph_store.c プロジェクト: huyba/biosal
void biosal_assembly_graph_store_get_vertex(struct thorium_actor *self, struct thorium_message *message)
{
    struct biosal_assembly_vertex vertex;
    struct biosal_dna_kmer kmer;
    void *buffer;
    struct biosal_assembly_graph_store *concrete_self;
    struct core_memory_pool *ephemeral_memory;
    struct thorium_message new_message;
    int new_count;
    void *new_buffer;
    struct biosal_assembly_vertex *canonical_vertex;
    int is_canonical;
    int path;
    int position;
    int count;

    path = -1;
    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);
    concrete_self = thorium_actor_concrete_actor(self);

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

    biosal_dna_kmer_init_empty(&kmer);

    position = 0;
    position += biosal_dna_kmer_unpack(&kmer, buffer, concrete_self->kmer_length,
                ephemeral_memory,
                &concrete_self->transport_codec);

    /*
     * Check if a path index was provided too.
     */
    if (position < count) {
        position += thorium_message_unpack_int(message, position, &path);
    }

    CORE_DEBUGGER_ASSERT_IS_EQUAL_INT(position, count);
    CORE_DEBUGGER_ASSERT(position == count);

    canonical_vertex = biosal_assembly_graph_store_find_vertex(self, &kmer);

    biosal_assembly_vertex_init_copy(&vertex, canonical_vertex);

    is_canonical = biosal_dna_kmer_is_canonical(&kmer, concrete_self->kmer_length,
                    &concrete_self->transport_codec);

    if (!is_canonical) {

        biosal_assembly_vertex_invert_arcs(&vertex);
    }

    biosal_dna_kmer_destroy(&kmer, ephemeral_memory);

    new_count = biosal_assembly_vertex_pack_size(&vertex);
    new_buffer = thorium_actor_allocate(self, new_count);

    biosal_assembly_vertex_pack(&vertex, new_buffer);

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

    thorium_actor_send_reply(self, &new_message);

    thorium_message_destroy(&new_message);
}
コード例 #12
0
ファイル: assembly_graph_store.c プロジェクト: huyba/biosal
void biosal_assembly_graph_store_add_arc(struct thorium_actor *self,
                struct biosal_assembly_arc *arc, char *sequence,
                void *key)
{
    struct biosal_assembly_graph_store *concrete_self;
    struct biosal_dna_kmer *source;
    struct biosal_dna_kmer real_source;
    int destination;
    int type;
    struct biosal_assembly_vertex *vertex;
    struct core_memory_pool *ephemeral_memory;
    int is_canonical;

#if 0
    /*
     * Don't do anything just to see if this code
     * is buggy.
     */

    return;
#endif

#ifdef BIOSAL_ASSEMBLY_GRAPH_STORE_DEBUG_ARC
    int verbose;
#endif

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

#ifdef BIOSAL_ASSEMBLY_GRAPH_STORE_DEBUG_ARC
    verbose = 0;

    if (concrete_self->received_arc_count == 0) {
        verbose = 1;
    }

    if (verbose) {
        printf("DEBUG BioSAL::GraphStore::AddArc\n");

        biosal_assembly_arc_print(arc, concrete_self->kmer_length, &concrete_self->transport_codec,
                    ephemeral_memory);
    }
#endif

    source = biosal_assembly_arc_source(arc);
    destination = biosal_assembly_arc_destination(arc);
    type = biosal_assembly_arc_type(arc);

    /*
     * Don't convert the data if the transport codec and the
     * storage codec are the same.
     */
    if (concrete_self->codec_are_different) {
        biosal_dna_kmer_get_sequence(source, sequence, concrete_self->kmer_length,
                        &concrete_self->transport_codec);
        biosal_dna_kmer_init(&real_source, sequence, &concrete_self->storage_codec,
                        ephemeral_memory);

        source = &real_source;
    }

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

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

#ifdef CORE_DEBUGGER_ENABLE_ASSERT
    if (vertex == NULL) {
        printf("Error: vertex is NULL, key_length_in_bytes %d size %" PRIu64 "\n",
                        concrete_self->key_length_in_bytes,
                        core_map_size(&concrete_self->table));
    }
#endif

    CORE_DEBUGGER_ASSERT(vertex != NULL);

#ifdef BIOSAL_ASSEMBLY_GRAPH_STORE_DEBUG_ARC
    if (verbose) {
        printf("DEBUG BEFORE:\n");
        biosal_assembly_vertex_print(vertex);
    }
#endif

    /*
     * Inverse the arc if the source is not canonical
     */
    is_canonical = biosal_dna_kmer_is_canonical(source, concrete_self->kmer_length,
                    &concrete_self->storage_codec);

    if (!is_canonical) {

        if (type == BIOSAL_ARC_TYPE_PARENT) {
            type = BIOSAL_ARC_TYPE_CHILD;

        } else if (type == BIOSAL_ARC_TYPE_CHILD) {

            type = BIOSAL_ARC_TYPE_PARENT;
        }

        destination = biosal_dna_codec_get_complement(destination);
    }

    if (type == BIOSAL_ARC_TYPE_PARENT) {

        biosal_assembly_vertex_add_parent(vertex, destination);

    } else if (type == BIOSAL_ARC_TYPE_CHILD) {

        biosal_assembly_vertex_add_child(vertex, destination);
    }

#ifdef BIOSAL_ASSEMBLY_GRAPH_STORE_DEBUG_ARC
    if (verbose) {
        printf("DEBUG AFTER:\n");
        biosal_assembly_vertex_print(vertex);
    }
#endif

    if (concrete_self->codec_are_different) {
        biosal_dna_kmer_destroy(&real_source, ephemeral_memory);
    }
}
コード例 #13
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);
}
コード例 #14
0
void biosal_coverage_distribution_receive(struct thorium_actor *self, struct thorium_message *message)
{
    int tag;
    struct core_map map;
    struct core_map_iterator iterator;
    int *coverage_from_message;
    uint64_t *count_from_message;
    uint64_t *frequency;
    int count;
    void *buffer;
    struct biosal_coverage_distribution *concrete_actor;
    int name;
    int source;
    struct core_memory_pool *ephemeral_memory;

    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);
    name = thorium_actor_name(self);
    source = thorium_message_source(message);
    concrete_actor = (struct biosal_coverage_distribution *)thorium_actor_concrete_actor(self);
    tag = thorium_message_action(message);
    count = thorium_message_count(message);
    buffer = thorium_message_buffer(message);

    if (tag == ACTION_PUSH_DATA) {

        core_map_init(&map, 0, 0);
        core_map_set_memory_pool(&map, ephemeral_memory);
        core_map_unpack(&map, buffer);

        core_map_iterator_init(&iterator, &map);


        while (core_map_iterator_has_next(&iterator)) {

            core_map_iterator_next(&iterator, (void **)&coverage_from_message,
                            (void **)&count_from_message);

#ifdef BIOSAL_COVERAGE_DISTRIBUTION_DEBUG
            thorium_actor_log(self, "DEBUG DATA %d %d\n", (int)*coverage_from_message, (int)*count_from_message);
#endif

            frequency = core_map_get(&concrete_actor->distribution, coverage_from_message);

            if (frequency == NULL) {

                frequency = core_map_add(&concrete_actor->distribution, coverage_from_message);

                (*frequency) = 0;
            }

            (*frequency) += (*count_from_message);
        }

        core_map_iterator_destroy(&iterator);

        thorium_actor_send_reply_empty(self, ACTION_PUSH_DATA_REPLY);

        concrete_actor->actual++;

        thorium_actor_log(self, "distribution/%d receives coverage data from producer/%d, %d entries / %d bytes %d/%d\n",
                        name, source, (int)core_map_size(&map), count,
                        concrete_actor->actual, concrete_actor->expected);

        if (concrete_actor->expected != 0 && concrete_actor->expected == concrete_actor->actual) {

            thorium_actor_log(self, "received everything %d/%d\n", concrete_actor->actual, concrete_actor->expected);

            biosal_coverage_distribution_write_distribution(self);

            thorium_actor_send_empty(self, concrete_actor->source,
                            ACTION_NOTIFY);
        }

        core_map_destroy(&map);

    } else if (tag == ACTION_ASK_TO_STOP) {

        biosal_coverage_distribution_ask_to_stop(self, message);

    } else if (tag == ACTION_SET_EXPECTED_MESSAGE_COUNT) {

        concrete_actor->source = source;
        thorium_message_unpack_int(message, 0, &concrete_actor->expected);

        thorium_actor_log(self, "distribution %d expects %d messages\n",
                        thorium_actor_name(self),
                        concrete_actor->expected);

        thorium_actor_send_reply_empty(self, ACTION_SET_EXPECTED_MESSAGE_COUNT_REPLY);
    }
}
コード例 #15
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);
}
コード例 #16
0
ファイル: assembly_graph_store.c プロジェクト: huyba/biosal
void biosal_assembly_graph_store_receive(struct thorium_actor *self, struct thorium_message *message)
{
    int tag;
    /*void *buffer;*/
    struct biosal_assembly_graph_store *concrete_self;
    double value;
    struct biosal_dna_kmer kmer;
    /*struct core_memory_pool *ephemeral_memory;*/
    int customer;
    int big_key_size;
    int big_value_size;

    if (thorium_actor_take_action(self, message)) {
        return;
    }

    /*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);*/

    if (tag == ACTION_SET_KMER_LENGTH) {

        thorium_message_unpack_int(message, 0, &concrete_self->kmer_length);

        biosal_dna_kmer_init_mock(&kmer, concrete_self->kmer_length,
                        &concrete_self->storage_codec, thorium_actor_get_ephemeral_memory(self));
        concrete_self->key_length_in_bytes = biosal_dna_kmer_pack_size(&kmer,
                        concrete_self->kmer_length, &concrete_self->storage_codec);
        biosal_dna_kmer_destroy(&kmer, thorium_actor_get_ephemeral_memory(self));

        big_key_size = concrete_self->key_length_in_bytes;
        big_value_size = sizeof(struct biosal_assembly_vertex);

        core_map_init(&concrete_self->table, big_key_size,
                        big_value_size);
        core_map_set_memory_pool(&concrete_self->table,
                        &concrete_self->persistent_memory);

        printf("DEBUG big_key_size %d big_value_size %d\n", big_key_size, big_value_size);

        /*
         * Configure the map for better performance.
         */
        core_map_disable_deletion_support(&concrete_self->table);

        /*
         * The threshold of the map is not very important because
         * requests that hit the map have to first arrive as messages,
         * which are slow.
         */
        core_map_set_threshold(&concrete_self->table, 0.95);

        thorium_actor_send_reply_empty(self, ACTION_SET_KMER_LENGTH_REPLY);

    } else if (tag == ACTION_ASSEMBLY_GET_KMER_LENGTH) {

        thorium_actor_send_reply_int(self, ACTION_ASSEMBLY_GET_KMER_LENGTH_REPLY,
                        concrete_self->kmer_length);

    } else if (tag == ACTION_RESET) {

        /*
         * Reset the iterator.
         */
        core_map_iterator_init(&concrete_self->iterator, &concrete_self->table);

        printf("DEBUG unitig_vertex_count %d\n",
                        concrete_self->unitig_vertex_count);

        thorium_actor_send_reply_empty(self, ACTION_RESET_REPLY);

    } else if (tag == ACTION_SEQUENCE_STORE_REQUEST_PROGRESS_REPLY) {

        thorium_message_unpack_double(message, 0, &value);

        core_map_set_current_size_estimate(&concrete_self->table, value);

    } else if (tag == ACTION_ASK_TO_STOP) {

        printf("%s/%d received %d arc blocks\n",
                        thorium_actor_script_name(self),
                        thorium_actor_name(self),
                        concrete_self->received_arc_block_count);

        thorium_actor_ask_to_stop(self, message);

    } else if (tag == ACTION_SET_CONSUMER) {

        thorium_message_unpack_int(message, 0, &customer);

        printf("%s/%d will use coverage distribution %d\n",
                        thorium_actor_script_name(self),
                        thorium_actor_name(self), customer);

        concrete_self->customer = customer;

        thorium_actor_send_reply_empty(self, ACTION_SET_CONSUMER_REPLY);

    } else if (tag == ACTION_PUSH_DATA) {

        printf("%s/%d receives ACTION_PUSH_DATA\n",
                        thorium_actor_script_name(self),
                        thorium_actor_name(self));

        biosal_assembly_graph_store_push_data(self, message);

    } else if (tag == ACTION_STORE_GET_ENTRY_COUNT) {

        thorium_actor_send_reply_uint64_t(self, ACTION_STORE_GET_ENTRY_COUNT_REPLY,
                        concrete_self->received);

    } else if (tag == ACTION_GET_RECEIVED_ARC_COUNT) {

        thorium_actor_send_reply_uint64_t(self, ACTION_GET_RECEIVED_ARC_COUNT_REPLY,
                        concrete_self->received_arc_count);
    }
}
コード例 #17
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);
}
コード例 #18
0
void biosal_assembly_arc_classifier_push_arc_block(struct thorium_actor *self, struct thorium_message *message)
{
    struct biosal_assembly_arc_classifier *concrete_self;
    int source;
    struct biosal_assembly_arc_block input_block;
    struct biosal_assembly_arc_block *output_block;
    struct core_vector output_blocks;
    struct core_memory_pool *ephemeral_memory;
    int consumer_count;
    struct core_vector *input_arcs;
    struct core_vector *output_arcs;
    int size;
    int i;
    struct biosal_assembly_arc *arc;
    void *buffer;
    int count;
    struct biosal_dna_kmer *kmer;
    int consumer_index;
    int arc_count;
    int consumer;
    struct thorium_message new_message;
    int new_count;
    void *new_buffer;
    int *bucket;
    int maximum_pending_requests;
    int maximum_buffer_length;
    int reservation;

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

    if (count == 0) {
        printf("Error, count is 0 (classifier_push_arc_block)\n");
        return;
    }

    concrete_self = (struct biosal_assembly_arc_classifier *)thorium_actor_concrete_actor(self);
    source = thorium_message_source(message);
    consumer_count = core_vector_size(&concrete_self->consumers);
    ephemeral_memory = thorium_actor_get_ephemeral_memory(self);

    CORE_DEBUGGER_LEAK_DETECTION_BEGIN(ephemeral_memory, classify_arcs);

    core_vector_init(&output_blocks, sizeof(struct biosal_assembly_arc_block));
    core_vector_set_memory_pool(&output_blocks, ephemeral_memory);

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

#ifdef BIOSAL_ASSEMBLY_ARC_CLASSIFIER_DEBUG
    printf("UNPACKING\n");
#endif

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

#ifdef BIOSAL_ASSEMBLY_ARC_CLASSIFIER_DEBUG
    printf("OK\n");
#endif

    input_arcs = biosal_assembly_arc_block_get_arcs(&input_block);

    /*
     * Configure the ephemeral memory reservation.
     */
    arc_count = core_vector_size(input_arcs);
    reservation = (arc_count / consumer_count) * 2;

    core_vector_resize(&output_blocks, consumer_count);

    CORE_DEBUGGER_ASSERT(!core_memory_pool_has_double_free(ephemeral_memory));

    /*
     * Initialize output blocks.
     * There is one for each destination.
     */
    for (i = 0; i < consumer_count; i++) {

        output_block = core_vector_at(&output_blocks, i);

        biosal_assembly_arc_block_init(output_block, ephemeral_memory, concrete_self->kmer_length,
                        &concrete_self->codec);

        biosal_assembly_arc_block_reserve(output_block, reservation);
    }

    size = core_vector_size(input_arcs);

    /*
     * Classify every arc in the input block
     * and put them in output blocks.
     */

#ifdef BIOSAL_ASSEMBLY_ARC_CLASSIFIER_DEBUG
    printf("ClassifyArcs arc_count= %d\n", size);

#endif

    CORE_DEBUGGER_ASSERT(!core_memory_pool_has_double_free(ephemeral_memory));

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

        arc = core_vector_at(input_arcs, i);

        kmer = biosal_assembly_arc_source(arc);

        consumer_index = biosal_dna_kmer_store_index(kmer, consumer_count,
                        concrete_self->kmer_length, &concrete_self->codec,
                        ephemeral_memory);

        output_block = core_vector_at(&output_blocks, consumer_index);

        /*
         * Make a copy of the arc and copy it.
         * It will be freed
         */

        biosal_assembly_arc_block_add_arc_copy(output_block, arc,
                        concrete_self->kmer_length, &concrete_self->codec,
                        ephemeral_memory);
    }

    /*
     * Input arcs are not needed anymore.
     */
    biosal_assembly_arc_block_destroy(&input_block, ephemeral_memory);

    CORE_DEBUGGER_ASSERT(!core_memory_pool_has_double_free(ephemeral_memory));

    /*
     * Finally, send these output blocks to consumers.
     */

    maximum_pending_requests = 0;
    maximum_buffer_length = 0;

    /*
     * Figure out the maximum buffer length tor
     * messages.
     */
    for (i = 0; i < consumer_count; i++) {

        output_block = core_vector_at(&output_blocks, i);
        new_count = biosal_assembly_arc_block_pack_size(output_block, concrete_self->kmer_length,
                    &concrete_self->codec);

        if (new_count > maximum_buffer_length) {
            maximum_buffer_length = new_count;
        }
    }

#if 0
    printf("POOL_BALANCE %d\n",
                    core_memory_pool_profile_balance_count(ephemeral_memory));
#endif

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

        output_block = core_vector_at(&output_blocks, i);
        output_arcs = biosal_assembly_arc_block_get_arcs(output_block);
        arc_count = core_vector_size(output_arcs);

        /*
         * Don't send an empty message.
         */
        if (arc_count > 0) {

            /*
             * Allocation is not required because new_count <= maximum_buffer_length
             */
            new_count = biosal_assembly_arc_block_pack_size(output_block, concrete_self->kmer_length,
                    &concrete_self->codec);

            new_buffer = thorium_actor_allocate(self, maximum_buffer_length);

            CORE_DEBUGGER_ASSERT(new_count <= maximum_buffer_length);

            biosal_assembly_arc_block_pack(output_block, new_buffer, concrete_self->kmer_length,
                    &concrete_self->codec);

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

            consumer = core_vector_at_as_int(&concrete_self->consumers, i);

            /*
             * Send the message.
             */
            thorium_actor_send(self, consumer, &new_message);
            thorium_message_destroy(&new_message);

            /* update event counters for control.
             */
            bucket = core_vector_at(&concrete_self->pending_requests, i);
            ++(*bucket);
            ++concrete_self->active_requests;

            if (*bucket > maximum_pending_requests) {
                maximum_pending_requests = *bucket;
            }

            if (*bucket > concrete_self->maximum_pending_request_count) {
                ++concrete_self->consumer_count_above_threshold;
            }
        }

        CORE_DEBUGGER_ASSERT(!core_memory_pool_has_double_free(ephemeral_memory));

#if 0
        printf("i = %d\n", i);
#endif

        /*
         * Destroy output block.
         */
        biosal_assembly_arc_block_destroy(output_block,
                    ephemeral_memory);

        CORE_DEBUGGER_LEAK_CHECK_DOUBLE_FREE(ephemeral_memory);
        CORE_DEBUGGER_ASSERT(!core_memory_pool_has_double_free(ephemeral_memory));
    }

    core_vector_destroy(&output_blocks);

    CORE_DEBUGGER_ASSERT(!core_memory_pool_has_double_free(ephemeral_memory));

    CORE_DEBUGGER_LEAK_CHECK_DOUBLE_FREE(ephemeral_memory);

    /*
     * Check if a response must be sent now.
     */

    ++concrete_self->received_blocks;
    concrete_self->source = source;

    /*
     * Only send a direct reply if there is enough memory.
     *
     * As long as maximum_pending_requests is lower than maximum_pending_request_count,
     * there is still space for at least one additional request.
     */
    if (maximum_pending_requests < concrete_self->maximum_pending_request_count
            && core_memory_has_enough_bytes()) {

        thorium_actor_send_empty(self, concrete_self->source,
                    ACTION_ASSEMBLY_PUSH_ARC_BLOCK_REPLY);
    } else {

        concrete_self->producer_is_waiting = 1;
    }

    CORE_DEBUGGER_LEAK_DETECTION_END(ephemeral_memory, classify_arcs);
}
コード例 #19
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);
}