Esempio n. 1
0
WEAK void CacheEntry::destroy() {
    halide_free(NULL, key);
    for (uint32_t i = 0; i < tuple_count; i++) {
        halide_device_free(NULL, &buffer(i));
        halide_free(NULL, get_pointer_to_header(buffer(i).host));
    }
}
Esempio n. 2
0
WEAK void CacheEntry::destroy() {
    halide_free(NULL, key);
    for (int32_t i = 0; i < tuple_count; i++) {
        halide_device_free(NULL, &buffer(i));
        halide_free(NULL, buffer(i).host - extra_bytes_host_bytes);
    }
}
Esempio n. 3
0
WEAK void CacheEntry::destroy() {
    for (uint32_t i = 0; i < tuple_count; i++) {
        halide_device_free(NULL, &buf[i]);
        halide_free(NULL, get_pointer_to_header(buf[i].host));
    }
    halide_free(NULL, metadata_storage);
}
Esempio n. 4
0
/** Free host and device memory associated with a buffer_t. */
WEAK int halide_device_and_host_free(void *user_context, struct halide_buffer_t *buf) {
    debug(user_context) << "halide_device_and_host_free: " << buf
                        << " buf dev " << buf->device
                        << " interface " << buf->device_interface << "\n";
    if (buf != NULL) {
        const halide_device_interface_t *device_interface = buf->device_interface;
        if (device_interface != NULL) {
            // Ensure interface is not freed prematurely.
            // TODO: Exception safety...
            device_interface->use_module();
            int result = device_interface->device_and_host_free(user_context, buf);
            device_interface->release_module();
            halide_assert(user_context, buf->device == 0);
            if (result) {
                return halide_error_code_device_free_failed;
            } else {
                return 0;
            }
        } else if (buf->host) {
            // device_free must have been called on this buffer (which
            // must be legal for the device interface that was
            // used). We'd better still free the host pointer.
            halide_free(user_context, buf->host);
            buf->host = NULL;
        }
    }
    buf->set_device_dirty(false);
    return 0;
}
Esempio n. 5
0
WEAK int halide_default_device_and_host_free(void *user_context, struct buffer_t *buf, const halide_device_interface *device_interface) {
    int result = halide_device_free(user_context, buf);
    halide_free(user_context, buf->host);
    buf->host = NULL;
    buf->host_dirty = false;
    buf->dev_dirty = false;
    return result;
}
Esempio n. 6
0
WEAK void prune_cache() {
#if CACHE_DEBUGGING
    validate_cache();
#endif
    CacheEntry *prune_candidate = least_recently_used;
    while (current_cache_size > max_cache_size &&
           prune_candidate != NULL) {
        CacheEntry *more_recent = prune_candidate->more_recent;
        
        if (prune_candidate->in_use_count == 0) {
            uint32_t h = prune_candidate->hash;
            uint32_t index = h % kHashTableSize;

            // Remove from hash table
            CacheEntry *prev_hash_entry = cache_entries[index];
            if (prev_hash_entry == prune_candidate) {
                cache_entries[index] = prune_candidate->next;
            } else {
                while (prev_hash_entry != NULL && prev_hash_entry->next != prune_candidate) {
                    prev_hash_entry = prev_hash_entry->next;
                }
                halide_assert(NULL, prev_hash_entry != NULL);
                prev_hash_entry->next = prune_candidate->next;
            }

            // Remove from less recent chain.
            if (least_recently_used == prune_candidate) {
                least_recently_used = more_recent;
            }
            if (more_recent != NULL) {
                more_recent->less_recent = prune_candidate->less_recent;
            }

            // Remove from more recent chain.
            if (most_recently_used == prune_candidate) {
                most_recently_used = prune_candidate->less_recent;
            }
            if (prune_candidate->less_recent != NULL) {
                prune_candidate->less_recent = more_recent;
            }

            // Decrease cache used amount.
            for (int32_t i = 0; i < prune_candidate->tuple_count; i++) {
                current_cache_size -= full_extent(prune_candidate->buffer(i));
            }

            // Deallocate the entry.
            prune_candidate->destroy();
            halide_free(NULL, prune_candidate);
        }

        prune_candidate = more_recent;
    }
#if CACHE_DEBUGGING
    validate_cache();
#endif
}
Esempio n. 7
0
WEAK int halide_default_device_and_host_free(void *user_context, struct halide_buffer_t *buf,
                                             const halide_device_interface_t *device_interface) {
    int result = halide_device_free(user_context, buf);
    if (buf->host) {
        halide_free(user_context, buf->host);
        buf->host = NULL;
    }
    buf->set_host_dirty(false);
    buf->set_device_dirty(false);
    return result;
}
Esempio n. 8
0
WEAK int halide_default_device_and_host_malloc(void *user_context, struct buffer_t *buf, const halide_device_interface *device_interface) {
    size_t size = buf_size(buf);
    buf->host = (uint8_t *)halide_malloc(user_context, size);
    if (buf->host == NULL) {
        return -1;
    }
    int result = halide_device_malloc(user_context, buf, device_interface);
    if (result != 0) {
        halide_free(user_context, buf->host);
        buf->host = NULL;
    }
    return result;
}
Esempio n. 9
0
WEAK void prune_cache() {
#if CACHE_DEBUGGING
    validate_cache();
#endif
    while (current_cache_size > max_cache_size &&
            least_recently_used != NULL) {
        CacheEntry *lru_entry = least_recently_used;
        uint32_t h = lru_entry->hash;
        uint32_t index = h % kHashTableSize;

        CacheEntry *entry = cache_entries[index];
        if (entry == lru_entry) {
            cache_entries[index] = lru_entry->next;
        } else {
            while (entry != NULL && entry->next != lru_entry) {
                entry = entry->next;
            }
            halide_assert(NULL, entry != NULL);
            entry->next = lru_entry->next;
        }
        least_recently_used = lru_entry->more_recent;
        if (least_recently_used != NULL) {
            least_recently_used->less_recent = NULL;
        }
        if (most_recently_used == lru_entry) {
            most_recently_used = NULL;
        }
        for (int32_t i = 0; i < lru_entry->tuple_count; i++) {
            current_cache_size -= full_extent(lru_entry->buffer(i));
        }

        lru_entry->destroy();
        halide_free(NULL, lru_entry);
    }
#if CACHE_DEBUGGING
    validate_cache();
#endif
}
Esempio n. 10
0
// Copy image data from texture back to host memory.
EXPORT int halide_opengl_copy_to_host(void *user_context, buffer_t *buf) {
    CHECK_INITIALIZED(1);
    if (!buf->dev_dirty) {
        return 0;
    }

    if (!buf->host || !buf->dev) {
#ifdef DEBUG
        print_buffer(user_context, buf);
#endif
        halide_error(user_context, "Invalid copy_to_host operation");
        return 1;
    }

    GLuint tex = get_texture_id(buf);
#ifdef DEBUG
    halide_printf(user_context, "halide_copy_to_host: %d\n", tex);
#endif

    GLint format;
    GLint type;
    if (!get_texture_format(user_context, buf, &format, &type)) {
        halide_error(user_context, "Invalid texture format\n");
        return 1;
    }
    GLint width = buf->extent[0];
    GLint height = buf->extent[1];

    ST.BindTexture(GL_TEXTURE_2D, tex);
    CHECK_GLERROR(1);
    bool is_interleaved =
        (buf->stride[2] == 1 && buf->stride[0] == buf->extent[2]);
    if (is_interleaved) {
        // TODO: GL_UNPACK_ROW_LENGTH
        ST.PixelStorei(GL_PACK_ROW_LENGTH, buf->extent[1]);
        ST.PixelStorei(GL_PACK_ALIGNMENT, 1);
        ST.GetTexImage(GL_TEXTURE_2D, 0, format, type, buf->host);
        CHECK_GLERROR(1);
    } else {
        #ifdef DEBUG
        halide_printf(user_context, "Warning: In copy_to_host, host buffer is not interleaved. Doing slow deinterleave.\n");
        #endif

        size_t size = width * height * buf->extent[2] * buf->elem_size;
        uint8_t *tmp = (uint8_t*)halide_malloc(user_context, size);

        ST.PixelStorei(GL_PACK_ALIGNMENT, 1);
        ST.GetTexImage(GL_TEXTURE_2D, 0, format, type, tmp);
        CHECK_GLERROR(1);

        switch (type) {
        case GL_UNSIGNED_BYTE:
            interleaved_to_halide<uint8_t>(buf, (uint8_t*)tmp, width, height, buf->extent[2]);
            break;
        case GL_UNSIGNED_SHORT:
            interleaved_to_halide<uint16_t>(buf, (uint16_t*)tmp, width, height, buf->extent[2]);
            break;
        case GL_FLOAT:
            interleaved_to_halide<float>(buf, (float*)tmp, width, height, buf->extent[2]);
            break;
        }

        halide_free(user_context, tmp);
    }

    ST.BindTexture(GL_TEXTURE_2D, 0);
    buf->dev_dirty = false;
    return 0;
}