Esempio n. 1
0
def write_scatter_root(builder, tr, inscription):
    builder.line("const std::vector<{0.type} > &$value = {1};",
                 inscription.edge.place,
                 inscription.expr)

    # Check size of vector
    builder.line("int $process_count = $thread->get_process_count();")
    builder.if_begin("$value.size() != $process_count")
    builder.line("fprintf(stderr, \"[scatter] Invalid size of vector (expected=%i, got=%zu)\\n\","
                    "$process_count, $value.size());")
    builder.line("exit(1);")
    builder.block_end()

    builder.if_begin("ca::is_trivially_packable<{0} >()", inscription.type)
    # Trivially packable
    builder.line("$thread->collective_scatter_root({0.id}, &$value[0], sizeof({1.type}));",
        tr, inscription)
    builder.else_if("ca::fixed_size<{0} >() != 0", inscription.type)
    # Fixed size
    builder.line("size_t $size = ca::fixed_size<{0} >();", inscription.type)
    builder.line("ca::Packer $packer($size * $process_count);")
    builder.line("ca::pack_with_step($packer, $value, $size);")
    builder.line("$thread->collective_scatter_root({0.id}, $packer.get_buffer(), $size);",
        tr, inscription)
    builder.line("$packer.free();")
    builder.write_else()
    # Generic case
    builder.line("int $process_id = $thread->get_process_id();")
    builder.line("ca::Packer $packer;")
    builder.line("int *$sizes = static_cast<int*>(alloca(sizeof(int) * $process_count));")
    builder.line("int *$displs = static_cast<int*>(alloca(sizeof(int) * (1 + $process_count)));")
    builder.line("$displs[0] = 0;")
    builder.for_begin("int $i = 0; $i < $process_id; $i++")
    builder.line("$packer << $value[$i];")
    builder.line("$displs[$i + 1] = $packer.get_size();")
    builder.line("$sizes[$i] = $displs[$i + 1] - $displs[$i];")
    builder.block_end()
    builder.line("$displs[$process_id + 1] = $displs[$process_id];")
    builder.line("$sizes[$process_id] = 0;")
    builder.for_begin("int $i = $process_id; $i < $process_count; $i++")
    builder.line("$packer << $value[$i];")
    builder.line("$displs[$i + 1] = $packer.get_size();")
    builder.line("$sizes[$i] = $displs[$i + 1] - $displs[$i];")
    builder.block_end()
    builder.line("$thread->collective_scatter_root({0.id}, $sizes, sizeof(int));", tr)
    builder.line("$thread->collective_scatterv_root("
                 "{0.id}, $packer.get_buffer(), $sizes, $displs);", tr)
    builder.line("$packer.free();")
    builder.block_end()

    buildnet.write_place_add(builder,
                    inscription.edge.place,
                    builder.expand("$n->"),
                    builder.expand("$value[$root]"),
                    bulk=False,
                    token=False)
    buildnet.write_activation(builder,
                              builder.expand("$n"),
                              inscription.edge.place.get_transitions_out())
Esempio n. 2
0
def write_allgather(builder, tr, inscription):
    t = parser.parse_typename(inscription.type, inscription.source)
    typename = t[1][0] # This should not failed, because check already verify this
    builder.line("ca::Token<std::vector<{0} > > *$token = new ca::Token<std::vector<{0} > >;",
                 typename)

    builder.if_begin("ca::is_trivially_packable<{0} >()", typename)
    # Trivially packable
    builder.line("const size_t $size = sizeof({0});", typename)
    builder.line("$token->value.resize($thread->get_process_count());")
    builder.line("$thread->collective_allgather({0.id}, &{1.expr}, $size, &$token->value[0]);",
                 tr, inscription)
    builder.else_if("ca::fixed_size<{0} >() != 0", typename)
    # Fixed size
    write_pack_fixed_size(builder, typename, inscription.expr)
    builder.line("void *$mem = malloc($size * $thread->get_process_count());")
    builder.line("$thread->collective_allgather({0.id}, $packer.get_buffer(), $size, $mem);",
                 tr, inscription)
    builder.line("$packer.free();")
    builder.line("ca::Unpacker $unpacker($mem, $size * $thread->get_process_count());")
    builder.line("ca::unpack_with_step($unpacker,"
                 "$token->value, $size, $thread->get_process_count());")

    builder.line("free($mem);")
    builder.write_else()
    # Generic case
    builder.line("int $process_count = $thread->get_process_count();")
    builder.line("int *$sizes = static_cast<int*>(alloca(sizeof(int) * $process_count));")
    builder.line("int *$displs = static_cast<int*>(alloca(sizeof(int) * (1 + $process_count)));")
    builder.line("int $size = 0;")
    builder.line("$thread->collective_allgather({0.id}, &$size, sizeof(int), $sizes);", tr)
    builder.line("$displs[0] = 0;")
    # Last displs[process_count] == sum of all sizes
    builder.for_begin("int $i = 0; $i < ca::process_count; $i++")
    builder.line("$displs[$i + 1] = $displs[$i] + $sizes[$i];")
    builder.block_end()
    builder.line("void *$mem = malloc($displs[$process_count]);")
    builder.line("$thread->collective_allgatherv({0.id}, &$size, 0, $mem, $sizes, $displs);", tr)
    builder.line("ca::Unpacker $unpacker($mem, $displs[$process_count]);")
    builder.line("int $process_id = $thread->get_process_id();")
    builder.line("ca::unpack_with_displs($unpacker, $token->value, $process_id, $displs);")
    builder.line("$token->value.push_back({0});", inscription.expr);
    builder.line("ca::unpack_with_displs"
                 "($unpacker, $token->value, $process_count - $process_id - 1,"
                             "$displs + $process_id + 1);")
    builder.line("free($mem);")
    builder.block_end()

    buildnet.write_place_add(builder,
                    inscription.edge.place,
                    builder.expand("$n->"),
                    builder.expand("$token"),
                    bulk=False,
                    token=True)
    buildnet.write_activation(builder,
                              builder.expand("$n"),
                              inscription.edge.place.get_transitions_out())
Esempio n. 3
0
def write_collective_body_simulation(builder, tr):
    inscription = tr.get_collective_inscription()
    op = tr.get_collective_operation()
    if op == "barrier":
        return
    if op == "gather":
        builder.if_begin("$root == $thread->get_process_id()")

    buildnet.write_place_add(builder,
                    inscription.edge.place,
                    builder.expand("$n->"),
                    builder.expand("$tokens->token_collective"),
                    bulk=False,
                    token=True)
    if op == "gather":
        builder.block_end()
Esempio n. 4
0
def write_scatter_nonroot(builder, tr, inscription):
    builder.line("const size_t $size = sizeof({0.type});", inscription)
    builder.line("ca::Token<{0.type} > *$token = new ca::Token<{0.type} >;",
                 inscription.edge.place)

    builder.if_begin("ca::is_trivially_packable<{0}>()", inscription.type)
    # Trivially packable
    builder.line(
        "$thread->collective_scatter_nonroot({0.id}, $root, &$token->value, $size);",
        tr)
    builder.else_if("ca::fixed_size<{0} >() != 0", inscription.type)
    # Fixed size
    builder.line("size_t $size = ca::fixed_size<{0} >();", inscription.type)
    builder.line("void *$mem = malloc($size * $thread->get_process_count());")
    builder.line(
        "$thread->collective_scatter_nonroot({0.id}, $root, $mem, $size);", tr)
    builder.line("ca::Unpacker $unpacker($mem);")
    builder.line("$unpacker >> $token->value;")
    builder.line("free($mem);")
    builder.write_else()
    # Generic case
    builder.line("int $size;")
    builder.line(
        "$thread->collective_scatter_nonroot({0.id}, $root, &$size, sizeof(int));",
        tr)
    builder.line("void *$mem = malloc($size);")
    builder.line(
        "$thread->collective_scatterv_nonroot({0.id}, $root, $mem, $size);",
        tr)
    builder.line("ca::Unpacker $unpacker($mem);")
    builder.line("$unpacker >> $token->value;")
    builder.line("free($mem);")
    builder.block_end()

    buildnet.write_place_add(builder,
                             inscription.edge.place,
                             builder.expand("$n->"),
                             builder.expand("$token"),
                             bulk=False,
                             token=True)
    buildnet.write_activation(builder, builder.expand("$n"),
                              inscription.edge.place.get_transitions_out())
Esempio n. 5
0
def write_bcast_root(builder, tr, inscription):
    # TODO: Reuse token when possible
    builder.line("const {0.type} &$value = {1};", inscription.edge.place,
                 inscription.expr)

    builder.if_begin("ca::is_trivially_packable<{0}>()", inscription.type)
    # Trivially packable
    builder.line(
        "$thread->collective_bcast_root({0.id}, &$value, sizeof({1.type}));",
        tr, inscription)
    builder.else_if("ca::fixed_size<{0} >() != 0", inscription.type)
    # Fixed size
    write_pack_fixed_size(builder, inscription.type, builder.expand("$value"))
    builder.line(
        "$thread->collective_bcast_root({0.id}, $packer.get_buffer(), $size);",
        tr, inscription)
    builder.line("$packer.free();")
    builder.write_else()
    # Generic case
    builder.line("int $process_id = $thread->get_process_id();")
    builder.line("ca::Packer $packer;")
    builder.line("$packer << $value;")
    builder.line("int $size = $packer.get_size();")
    builder.line(
        "$thread->collective_bcast_root({0.id}, &$size, sizeof(int));", tr)
    builder.line(
        "$thread->collective_bcast_root("
        "{0.id}, $packer.get_buffer(), $size);", tr)
    builder.line("$packer.free();")
    builder.block_end()

    buildnet.write_place_add(builder,
                             inscription.edge.place,
                             builder.expand("$n->"),
                             builder.expand("$value"),
                             bulk=False,
                             token=False)
    buildnet.write_activation(builder, builder.expand("$n"),
                              inscription.edge.place.get_transitions_out())
Esempio n. 6
0
def write_bcast_root(builder, tr, inscription):
    # TODO: Reuse token when possible
    builder.line("const {0.type} &$value = {1};",
                 inscription.edge.place,
                 inscription.expr)

    builder.if_begin("ca::is_trivially_packable<{0} >()", inscription.type)
    # Trivially packable
    builder.line("$thread->collective_bcast_root({0.id}, &$value, sizeof({1.type}));",
        tr, inscription)
    builder.else_if("ca::fixed_size<{0} >() != 0", inscription.type)
    # Fixed size
    write_pack_fixed_size(builder, inscription.type, builder.expand("$value"))
    builder.line("$thread->collective_bcast_root({0.id}, $packer.get_buffer(), $size);",
        tr, inscription)
    builder.line("$packer.free();")
    builder.write_else()
    # Generic case
    builder.line("int $process_id = $thread->get_process_id();")
    builder.line("ca::Packer $packer;")
    builder.line("$packer << $value;")
    builder.line("int $size = $packer.get_size();")
    builder.line("$thread->collective_bcast_root({0.id}, &$size, sizeof(int));", tr)
    builder.line("$thread->collective_bcast_root("
                 "{0.id}, $packer.get_buffer(), $size);", tr)
    builder.line("$packer.free();")
    builder.block_end()

    buildnet.write_place_add(builder,
                    inscription.edge.place,
                    builder.expand("$n->"),
                    builder.expand("$value"),
                    bulk=False,
                    token=False)
    buildnet.write_activation(builder,
                              builder.expand("$n"),
                              inscription.edge.place.get_transitions_out())
Esempio n. 7
0
def write_scatter_nonroot(builder, tr, inscription):
    builder.line("const size_t $size = sizeof({0.type});", inscription)
    builder.line("ca::Token<{0.type} > *$token = new ca::Token<{0.type} >;",
            inscription.edge.place)

    builder.if_begin("ca::is_trivially_packable<{0} >()", inscription.type)
    # Trivially packable
    builder.line("$thread->collective_scatter_nonroot({0.id}, $root, &$token->value, $size);", tr)
    builder.else_if("ca::fixed_size<{0} >() != 0", inscription.type)
    # Fixed size
    builder.line("size_t $size = ca::fixed_size<{0} >();", inscription.type)
    builder.line("void *$mem = malloc($size * $thread->get_process_count());")
    builder.line("$thread->collective_scatter_nonroot({0.id}, $root, $mem, $size);", tr)
    builder.line("ca::Unpacker $unpacker($mem, $size * $thread->get_process_count());")
    builder.line("$unpacker >> $token->value;")
    builder.line("free($mem);")
    builder.write_else()
    # Generic case
    builder.line("int $size;")
    builder.line("$thread->collective_scatter_nonroot({0.id}, $root, &$size, sizeof(int));", tr)
    builder.line("void *$mem = malloc($size);")
    builder.line("$thread->collective_scatterv_nonroot({0.id}, $root, $mem, $size);", tr)
    builder.line("ca::Unpacker $unpacker($mem, $size);")
    builder.line("$unpacker >> $token->value;")
    builder.line("free($mem);")
    builder.block_end()

    buildnet.write_place_add(builder,
                    inscription.edge.place,
                    builder.expand("$n->"),
                    builder.expand("$token"),
                    bulk=False,
                    token=True)
    buildnet.write_activation(builder,
                              builder.expand("$n"),
                              inscription.edge.place.get_transitions_out())